首页 > 其他分享 >队列

队列

时间:2024-04-02 16:22:35浏览次数:12  
标签:std head 队列 value tail unique ptr

#include <iostream>
#include <mutex>
#include <condition_variable>
#include <memory>

template<typename T> 
class ThreadSafeQueue {
private:  
    struct Node {  
        std::shared_ptr<T> p_data; //指向数据块
        std::unique_ptr<Node> next;
    }; 
    std::unique_ptr<Node> head;//头
    Node* tail;  //尾
    mutable std::mutex mtx_head; 
    mutable std::mutex mtx_tail;
    std::condition_variable con_push; //数据入队通知

public:
    ThreadSafeQueue():head(new Node),tail(head.get()) {}
    ~ThreadSafeQueue() {
        while(head){
            head = std::move(head->next);
        }
        tail = nullptr;
    }
    ThreadSafeQueue(const ThreadSafeQueue&)=delete;
    ThreadSafeQueue& operator=(const ThreadSafeQueue&)=delete;

private:
    Node* get_tail() {
        std::lock_guard<std::mutex> lock_tail(mtx_tail);
        return tail;
    }
  
    std::unique_ptr<Node> pop_head()
    {
        std::unique_ptr<Node> old_head=std::move(head);
        head=std::move(old_head->next);
        return old_head;
    }
  
    std::unique_ptr<Node> try_pop_head(T& value)
    {
        std::lock_guard<std::mutex> head_lock(mtx_head);
        if(head.get()==get_tail())
        {
            return std::unique_ptr<Node>();
        }
        value=std::move(*head->p_data);
        return pop_head();
    }
  
    std::unique_ptr<Node> wait_pop_head(T& value)
    {
        std::unique_lock<std::mutex> head_lock(mtx_head);
        con_push.wait(head_lock,[&]{return head.get()!=get_tail();});
        value=*head->p_data;
        return pop_head();
    }

public:
    void push(T value) { 
        //构造数据块
        std::shared_ptr<T> new_data(std::make_shared<T>(value));
        //构造新节点
        std::unique_ptr<Node> new_node(new Node); //会被当做新的虚拟节点
        {
            //操作尾部指针,先加锁
            std::lock_guard<std::mutex> tail_lock(mtx_tail);
            tail->p_data = new_data; //数据块挂载
            tail->next = std::move(new_node); 
            tail = (tail->next).get();//指向新的虚拟节点
        }
        con_push.notify_one();  
    }
    
    bool try_pop(T& value) {
        std::unique_ptr<Node> const old_head=try_pop_head(value);
        return old_head != nullptr;        
    }
    
    void wait_and_pop(T& value)
    {
        std::unique_ptr<Node> const old_head=wait_pop_head(value);
    }
};

  

标签:std,head,队列,value,tail,unique,ptr
From: https://www.cnblogs.com/fchy822/p/18110841

相关文章

  • 关于用栈和队列分别解决走迷宫问题的方法讨论(参与者:陈卓,毛敏磊)
    对于生活中最常见的小游戏——走迷宫,相信大家都不陌生,人为走相信大家都会走,但能不能用代码实现,我们认为是可以的,以下是我们对如何走迷宫的一些看法和代码实现(cz负责队列解决,mml负责用栈解决):1.关于用队列解决:先简单介绍一下队列:队列是一种操作受限的线性表,只允许在表的一端进行插......
  • 消息队列
    消息队列的作用解耦异步消峰1.解耦在没有使用消息队列前档案归档,在没有使用消息队列前,上游系统将数据推送到CDAS后,CDAS将数据先存入DB中,然后启用定时任务定时对数据进行处理定时任务间隔、单次任务处理任务数据数量都不好控制业务处理过程中需要调用其他系统的......
  • Offer必备算法20_队列_宽搜bfs_四道力扣题详解(由易到难)
    目录①力扣429.N叉树的层序遍历解析代码②力扣103.二叉树的锯齿形层序遍历解析代码③力扣662.二叉树最大宽度解析代码④力扣515.在每个树行中找最大值解析代码本篇完。①力扣429.N叉树的层序遍历429.N叉树的层序遍历难度中等给定一个N叉树,返回其节......
  • 评测机队列(牛吃草问题)
    1.问题2.解决2.1分析关键思路是利用好支点,这里具体评测机的评测速度是未知的,但是我们写出方程组则可以发现,该速度是可以约去的,这时我们不妨设置为最简单的1个程序/min2.2代码#include<bits/stdc++.h>usingnamespacestd;intmain(){ intn1=8,t1=30,n2=10,......
  • 13天【代码随想录算法训练营34期】 第五章 栈与队列part03(● 239. 滑动窗口最大值 ●
    239.滑动窗口最大值单调队列:单调递减,一个queue,最大值在queue口,队列中只维护有可能为最大值的数字比如说1,3,2,4;当slidingwindow已经到3时,就可以把1pop出去了,因为有了3,1不可能为最大值,同理到4的时候,3、2都可以pop出去classMyQueue:def__init__(self):self.queue......
  • 如何使用PHP和Redis实现消息队列功能?
    前言今天,我们继续讲消息队列,如何使用Redis实现消息队列的功能。前期准备,需要安装好docker、docker-compose的运行环境。PHP的项目运行环境可以参考下面的文章内容。如何使用docker部署php服务-CSDN博客前面我们也讲了PHP和RabbitMQ实现消息队列的功能,感兴趣的可以查看下面......
  • 链式队列实现
    typedefstructlist//创建队列中的链式结构{ datatypedata;//数据域 structlist*next;//指针域}list;typedefstructqueue//创建队列{ list*front;//队头 list*rear;//队尾}queue;voidinitqueue(queue*q)//初始化队列{ q->front=q->rear=(list*)mal......
  • Python数据结构与算法——数据结构(栈、队列)
    目录数据结构介绍列表栈栈的基本操作:栈的实现(使用一般列表结构即可实现):栈的应用——括号匹配问题队列队列的实现方式——环形队列 队列的实现方式——双向队列 队列内置模块栈和队列应用——迷宫问题栈——深度优先搜索 队列——广度优先搜索数据结构介绍......
  • 11天【代码随想录算法训练营34期】 第五章 栈与队列part02(● 20. 有效的括号 ● 1047
    20.有效的括号classSolution:defisValid(self,s:str)->bool:stk=[]upper=["(","{","["]lower=[")","}","]"]dictionary={")":"(&qu......
  • 代码随想录算法训练营第11天 | 栈和队列
    20.有效的括号遇到左括号入栈,遇到右括号弹出boolisValid(strings){ stack<char>kuohao; charc; for(chara:s){ switch(a) { case'(': case'{': case'[': kuohao.push(a); break; case')': case'......