c++11 多线程编程——如何实现线程安全队列

标题1:c++11多线程编程——如何实现线程安全队列

转眼间,多线程编程已经成为了现代软件开发中必不可少的一项技能,而线程安全队列则是其中非常重要的一个思路,下面我们就来详细讲解一下如何在c++11中实现线程安全队列。

标题2:实现方法1:使用锁

使用锁是最常见、最简单的实现线程安全队列的方法。

示例1:

#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>

template<typename T>
class Queue {
private:
    std::queue<T> m_queue;
    std::mutex m_mutex;
    std::condition_variable m_cv; 

public:
    void push(const T& item) {
        std::lock_guard<std::mutex> lock(m_mutex);
        m_queue.push(item);
        m_cv.notify_one();
    }

    bool pop(T& item) {
        std::unique_lock<std::mutex> lock(m_mutex);
        m_cv.wait(lock, [this] {return !m_queue.empty(); });
        if (m_queue.empty()) {
            return false;
        }
        item = std::move(m_queue.front());
        m_queue.pop();
        return true;
    }

    bool empty() const {
        std::lock_guard<std::mutex> lock(m_mutex);
        return m_queue.empty();
    }
};

示例2:

#include <iostream>
#include <thread>

Queue<int> my_queue;

void producer() {
    for (int i = 1; i <= 10; i++) {
        my_queue.push(i);
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
}

void consumer() {
    int item = 0;
    for (int i = 1; i <= 10; i++) {
        while (!my_queue.pop(item)) {
            std::this_thread::sleep_for(std::chrono::milliseconds(10));
        }
        std::cout << "Item " << item << " is popped." << std::endl;
    }
}

int main() {
    std::thread producer_thread(producer);
    std::thread consumer_thread(consumer);
    producer_thread.join();
    consumer_thread.join();
}

思路解析:

示例1中给出了一个基本的线程安全队列实现,其中的锁和条件变量是保证线程安全的关键,push、pop和empty三个函数分别实现了队列的插入、删除和判空操作,并且在push操作中通过条件变量通知等待队列的线程。示例2则是一个简单的测试程序,通过开启一个生产者线程和一个消费者线程,验证了线程安全队列的正确性。

标题3:实现方法2:使用原子操作

相比于使用锁的方式,原子操作是一种更轻量级的实现线程安全的方法,既可以避免死锁等锁相关的问题,同时还能够提供更高的并发性。

示例1:

#include <queue>
#include <thread>
#include <atomic>
#include <chrono>

template<typename T>
class Queue {
private:
    std::queue<T> m_queue;
    std::atomic_bool m_flag;

public:
    Queue() : m_flag(false) {}

    void push(const T& item) {
        m_queue.push(item);
        m_flag.store(true, std::memory_order_release);
    }

    bool pop(T& item) {
        if (m_flag.load(std::memory_order_acquire)) {
            if (!m_queue.empty()) {
                item = std::move(m_queue.front());
                m_queue.pop();
                return true;
            }
            else {
                m_flag.store(false, std::memory_order_release);
            }
        }
        return false;
    }

    bool empty() const {
        return m_queue.empty();
    }
};

示例2:

#include <iostream>
#include <thread>

Queue<int> my_queue;

void producer() {
    for (int i = 1; i <= 10; i++) {
        my_queue.push(i);
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
}

void consumer() {
    int item = 0;
    for (int i = 1; i <= 10; i++) {
        while (!my_queue.pop(item)) {
            std::this_thread::sleep_for(std::chrono::milliseconds(10));
        }
        std::cout << "Item " << item << " is popped." << std::endl;
    }
}

int main() {
    std::thread producer_thread(producer);
    std::thread consumer_thread(consumer);
    producer_thread.join();
    consumer_thread.join();
}

思路解析:

示例1中实现的线程安全队列使用了std::atomic_bool类型的m_flag,同时还使用了memory_order_release和memory_order_acquire等原子操作来保证线程安全,其中前者用于push操作,后者用于pop操作,同时在pop中还对队列为空的情况进行了判断,并且在队列变为空时,将m_flag重置为false,以通知未来的push操作继续往队列中插入元素。示例2同样是对线程安全队列的基本测试程序。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:c++11 多线程编程——如何实现线程安全队列 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • Java实现的两个线程同时运行案例

    下面我将给出一个完整的Java实现的两个线程同时运行的案例攻略。 步骤1:创建两个线程 创建两个线程,继承Thread类并重写run()方法,实现自己的线程逻辑。 示例1: class ThreadOne extends Thread { @Override public void run() { for (int i = 1; i <= 10; i+…

    多线程 2023年5月16日
    00
  • python 并发编程 多路复用IO模型详解

    Python 并发编程 多路复用IO模型详解 一、什么是多路复用IO模型 在传统的 I/O 模型中,当一个线程或者进程要进行 I/O 操作的时候,会阻塞当前的任务,等待 I/O 完成后才能继续执行后续的任务。这种模式既浪费时间,也浪费资源,无法高效地利用 CPU。 多路复用 IO 模型是一种更加高效的 I/O 处理模型,在这种模式下,可以实现多个 I/O 任…

    多线程 2023年5月16日
    00
  • Python多线程编程(一):threading模块综述

    标题:Python多线程编程(一):threading模块综述 正文: 多线程编程是指在一个进程内,有多个线程同时执行,这些线程共享进程的内存空间和系统资源。Python提供了多种多线程编程的方式,其中最常用的方式之一是使用threading模块。 threading模块简介 threading模块是Python解释器内置的模块,主要用于支持多线程编程。它提…

    多线程 2023年5月17日
    00
  • JAVA多线程的使用场景与注意事项总结

    我们来讲解“JAVA多线程的使用场景与注意事项总结”。首先,需要了解什么是多线程。多线程是指在同一时间内,处理不同任务的能力。在JAVA中,多线程基于线程对象(Thread对象)实现。 一、多线程的使用场景 多线程的使用场景包括以下几个方面: 1.1 处理耗时的操作 当需要处理耗时的操作时,比如进行网络IO操作、从磁盘读取数据、计算复杂数学函数等,使用多线程…

    多线程 2023年5月17日
    00
  • Java多线程 自定义线程池详情

    Java多线程 自定义线程池详情 什么是线程池? 线程池是一种线程复用的机制,用于管理与分配线程。在程序中,线程池预先为一组可重用的线程分配了一定数量的线程。这些线程对于一定数量的任务是可用的。一旦指定了任务,就将任务放入队列中排队等待线程。一旦有可用的线程,它就会从队列中取出一个任务并处理它。 JDK内置的线程池 在JDK中,可以使用Executors类创…

    多线程 2023年5月17日
    00
  • 简单的易语言多线程应用实例

    简单的易语言多线程应用实例 概念介绍 多线程(Multithreading)是计算机科学中的一个概念,是指同一程序可以同时执行多个线程(Thread)的技术。在多线程应用程序运行的时候,会有多个线程同时运行,每个线程都有独立的执行空间,并且分别执行不同的子任务。 在易语言中,可以通过 Thread 函数实现多线程。通过 Thread 函数创建的线程称为子线程…

    多线程 2023年5月16日
    00
  • Linux多线程编程(一)

    Linux多线程编程(一) 前言 Linux是一个多线程的操作系统,可以支持多个并发执行的程序。多线程编程可以充分利用多核CPU,在并发执行的情况下提高程序的性能,同时也可以编写出体验更加流畅、响应更快的应用程序。 本文将介绍Linux多线程编程,并提供两个示例说明,分别演示线程的创建和同步。 线程创建 在Linux中,线程的创建依赖于pthread库,因此…

    多线程 2023年5月17日
    00
  • Python 多线程的实例详解

    以下是“Python 多线程的实例详解”的完整攻略。 Python多线程的概念 Python多线程是指在同一时间内运行多个线程。在处理多任务时,多线程技术可以大幅提高程序的运行效率。在Python中,有两种实现多线程的方式,分别是_thread模块和threading模块。其中,_thread是低级模块,threading是高级模块,使用threading模…

    多线程 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部