使用C++构建安全队列

这篇具有很好参考价值的文章主要介绍了使用C++构建安全队列。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 背景

  • STL的容器不是线程安全的,我们经常会有需求要求数据结构线程安全,比如写生产者消费者模型的时候,就要求队列线程安全。
  • 利用std::queue和C++线程标准库的一些组件(mutex,condition_variable),可以写一个线程安全的队列ConcurrenceQueue。

2 思路梳理

需要4个函数

  • push,入队;
  • pop,出队并返回原来对头的元素,如果为队空则阻塞
  • tryPop,出队并返回原来对头的元素,如果队空返回空(使用智能指针作返回类型),非阻塞
  • empty,返回是否为空,实则没啥用,多线程条件下判空,下一瞬间另一线程就可能push进去东西了。

3 实现代码

#ifndef __CONCURRENCEQUEUE_H__
#define __CONCURRENCEQUEUE_H__
#include <mutex>
#include <condition_variable>
#include <deque>
#include <queue>
#include <memory>

template<typename DATATYPE, typename SEQUENCE = std::deque<DATATYPE>>
class ConcurrenceQueue 
{
public:
    ConcurrenceQueue() = default;
    
    ConcurrenceQueue(const ConcurrenceQueue & other)
    {
        std::lock_guard<std::mutex> lg(other.m_mutex);
        m_data = other.m_data;
    }
    ConcurrenceQueue(ConcurrenceQueue &&) = delete;
    ConcurrenceQueue & operator= (const ConcurrenceQueue &) = delete;
    ~ConcurrenceQueue() = default;
    bool empty() const 
    {
        std::lock_guard<std::mutex> lg(m_mutex);
        return m_data.empty();
    }
    
    void push(const DATATYPE & data) 
    {
        std::lock_guard<std::mutex> lg(m_mutex);
        m_data.push(data);
        m_cond.notify_one();
    }
    
    void push(DATATYPE && data) 
    {
        std::lock_guard<std::mutex> lg(m_mutex);
        m_data.push(std::move(data));
        m_cond.notify_one();
    }
    
    std::shared_ptr<DATATYPE> tryPop() 
    {  // 非阻塞
        std::lock_guard<std::mutex> lg(m_mutex);
        if (m_data.empty()) return {};
        auto res = std::make_shared<DATATYPE>(m_data.front());
        m_data.pop();
        return res;
    }
    
    std::shared_ptr<DATATYPE> pop() 
    {  // 非阻塞
        std::unique_lock<std::mutex> lg(m_mutex);
        m_cond.wait(lg, [this] { return !m_data.empty(); });
        auto res = std::make_shared<DATATYPE>(std::move(m_data.front()));
        m_data.pop();
        return res;
    }
    
private:
    std::queue<DATATYPE, SEQUENCE> m_data;
    mutable std::mutex m_mutex;
    std::condition_variable m_cond;
};
#endif

 4 测试

全局的:

ConcurrenceQueue<int> g_queue;

void producer() 
{    
    for (int i = 0; i < 100; ++i) 
    {
        g_queue.push(i);
        std::this_thread::sleep_for(std::chrono::seconds(3));
    }
}

void consumer1() 
{
    while (1) 
    {
        std::printf("[1]  -------   %d\n", *g_queue.pop());
    }
}

void consumer2() 
{
    while (1) 
    {
        auto front = g_queue.tryPop();
        std::printf("[2]  -------   %d\n", front ? *front : -1);
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

测试 1:(消费者阻塞式消费)

int main () 
{
    std::thread t1(producer);
    std::thread t2(consumer1);

    t1.join();
    t2.join();
    return 0;
}

测试 2:(消费者非阻塞式消费,但要sleep轮询)

int main () 
{
    std::thread t1(producer);
    std::thread t2(consumer2);

    t1.join();
    t2.join();
    return 0;
}

后面发现这个博客也不错:

c++ 带超时的线程安全队列 ThreadSafeQueue-CSDN博客文章来源地址https://www.toymoban.com/news/detail-717757.html

到了这里,关于使用C++构建安全队列的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++多线程--线程安全的队列实现(基于锁)

    本文主要是根据C++ Concurrency in Action (豆瓣)第6章的基于锁的数据结构来讲解相应的队列实现。 本文会给出两种队列 基于STL的queue的线程安全队列 基于链表的线程安全队列 如何实现一个线程安全的队列?需要遵循什么样的准则? 可参考: C++多线程--发现接口间固有竞争_qls31

    2024年02月04日
    浏览(34)
  • 【Linux | C++ 】基于环形队列的多生产者多消费者模型(Linux系统下C++ 代码模拟实现)

    在上一篇文章中,我们深入探讨了Linux操作系统中的POSIX信号量,这是一个强大的同步机制,用于协调进程或线程对共享资源的访问。通过对信号量的深入理解和应用,我们学习了如何有效地解决并发编程中的竞争条件,确保程序的稳定性和效率。随着并发编程技术的不断深入

    2024年02月21日
    浏览(67)
  • 构建稳固基石:C++线程安全Map的简单实现与应用

      概述: 实现线程安全的C++ map是为了在多线程环境中确保对共享数据的安全访问。通过封装std::map和使用std::mutex互斥锁,该实现提供了插入、获取、删除等线程安全操作,有效解决了潜在的竞态条件和数据一致性问题。以下是一个简单的示例代码,演示了该线程安全map的基

    2024年03月09日
    浏览(37)
  • Linux--构建安全的SSH服务体系

           某公司的电子商务站点由专门的网站管理员进行配置和维护,并需要随时从Internet进行远程管理,考虑到易用性和灵活性,在Web服务器上启用OpenSSH服务,同时基于安全性考虑,需要对 SSH登录进行严格的控制,如图10.4所示。 需求描述 允许网站管理员wzadm通过笔记本电

    2024年01月21日
    浏览(30)
  • 【C++】队列(queue)的使用

    C++ 中, std::queue 容器是一种 先进先出 (First In First Out, FIFO)的数据结构,且有两个出口。 队列(queue)的 结构 如下:类似于生活中的排队买票,最先排队的人位于队伍最前端,后来的人依次从队伍末尾加入队伍。当队首的人买票成功后离开,原先位于第二位的人顶上成为新的队

    2024年02月09日
    浏览(37)
  • 【小沐学C++】C++ 基于CMake构建工程项目(Windows、Linux)

    官网地址: https://cmake.org CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。只是 CMake 的组态档取名为 CMakeLists.txt。 (1)官网下载地址

    2024年02月13日
    浏览(35)
  • 【C++】通过栈和队列学会使用适配器和优先队列学会仿函数的使用

    🌇个人主页:平凡的小苏 📚学习格言:命运给你一个低的起点,是想看你精彩的翻盘,而不是让你自甘堕落,脚下的路虽然难走,但我还能走,比起向阳而生,我更想尝试逆风翻盘 。 🛸 C++专栏 : C++内功修炼基地 家人们更新不易,你们的👍点赞👍和⭐关注⭐真的对我真

    2024年02月16日
    浏览(44)
  • 队列的使用以及模拟实现(C++版本)

    🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻强烈推荐优质专栏: 🍔🍟🌯C++的世界(持续更新中) 🐻推荐专栏1: 🍔🍟🌯C语言初阶 🐻推荐专栏2: 🍔🍟🌯C语言进阶 🔑个人信条: 🌵知行合一 🍉本篇简介::讲解队列的使用以及模拟实现 金句分享: ✨来日方长,未来是星辰大海般璀

    2024年02月08日
    浏览(25)
  • C++ 优先队列 priority_queue 使用篇

    目录 1.储备知识    (1)数据结构:堆   (2)仿函数(函数对象)     [1]理解仿函数     [2]实现仿函数   (3)priority_queue理解     [1]什么是priority_queue (优先队列)?     [2]优先队列性质 2.priority_queue的参数理解(重要!!!)   (1)priority_queue的参数     [1]priority_queue类模板参数     [

    2024年03月12日
    浏览(81)
  • 多线程环境下如何安全的使用线性表, 队列, 哈希表

    内心丰盈者, 独行也如众 使用synchronized锁或者reentrantLock锁 使用CopyOnWriteArrayList(COW写时拷贝)类来代替ArrayList类. 多个线程对CopyOnWriteArrayList里面的ArrayList进行读操作, 不会发生线程安全问题, 不做任何处理 多个线程对CopyOnWriteArrayList里面的ArrayList进行写操作, 会为每个线程创建一

    2024年02月07日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包