c – 为什么std :: queue不是线程安全的?

c – 为什么std :: queue不是线程安全的?,第1张

概述话题说明了这一点.我不明白为什么std :: queue(或者通常:任何队列)本质上不是线程安全的,当没有涉及其他数据结构的迭代器时. 根据共同的规则 >至少有一个帖子写给… >另一个线程正在从共享资源中读取 我应该在以下示例代码中遇到冲突: #include "stdafx.h"#include <queue>#include <thread>#include <iostream>st 话题说明了这一点.我不明白为什么std :: queue(或者通常:任何队列)本质上不是线程安全的,当没有涉及其他数据结构的迭代器时.

根据共同的规则

>至少有一个帖子写给…
>另一个线程正在从共享资源中读取

我应该在以下示例代码中遇到冲突:

#include "stdafx.h"#include <queue>#include <thread>#include <iostream>struct response{    static int & getCount()    {        static int theCount = 0;        return theCount;    }    int ID;};std::queue<response> queue;// generate 100 response objects and push them into the queuevoID produce(){    for (int i = 0; i < 100; i++)    {        response r;         r.ID = response::getCount()++;        queue.push(r);        std::cout << "produced: " << r.ID << std::endl;    }}// get the 100 first responses from the queuevoID consume(){    int consumedCounter = 0;    for (;;)    {               if (!queue.empty())        {            std::cout << "consumed: " << queue.front().ID << std::endl;            queue.pop();            consumedCounter++;        }        if (consumedCounter == 100)            break;    }}int _tmain(int argc,_TCHAR* argv[]){    std::thread t1(produce);    std::thread t2(consume);    t1.join();    t2.join();    return 0;}

一切似乎都很好:
– 没有违反完整性/数据损坏
– 消费者获得它们的元素的顺序是正确的(0 <1 <3 <4 ......),当然是产品的顺序.和利弊.打印是随机的,因为没有涉及信令.

解决方法 想象一下,你检查!queue.empty(),进入下一个块,在进入queue.first()之前,另一个线程将删除(d出)唯一的元素,因此你查询一个空队列.

使用如下所示的同步队列

#pragma once#include <queue>#include <mutex>#include <condition_variable>    template <typename T>    class SharedQueue    {    public:        SharedQueue();        ~SharedQueue();        T& front();        voID pop_front();        voID push_back(const T& item);        voID push_back(T&& item);        int size();        bool empty();    private:        std::deque<T> queue_;        std::mutex mutex_;        std::condition_variable cond_;    };     template <typename T>    SharedQueue<T>::SharedQueue(){}    template <typename T>    SharedQueue<T>::~SharedQueue(){}    template <typename T>    T& SharedQueue<T>::front()    {        std::unique_lock<std::mutex> mlock(mutex_);        while (queue_.empty())        {            cond_.wait(mlock);        }        return queue_.front();    }    template <typename T>    voID SharedQueue<T>::pop_front()    {        std::unique_lock<std::mutex> mlock(mutex_);        while (queue_.empty())        {            cond_.wait(mlock);        }        queue_.pop_front();    }         template <typename T>    voID SharedQueue<T>::push_back(const T& item)    {        std::unique_lock<std::mutex> mlock(mutex_);        queue_.push_back(item);        mlock.unlock();     // unlock before notificiation to minimize mutex con        cond_.notify_one(); // notify one waiting thread    }    template <typename T>    voID SharedQueue<T>::push_back(T&& item)    {        std::unique_lock<std::mutex> mlock(mutex_);        queue_.push_back(std::move(item));        mlock.unlock();     // unlock before notificiation to minimize mutex con        cond_.notify_one(); // notify one waiting thread    }    template <typename T>    int SharedQueue<T>::size()    {        std::unique_lock<std::mutex> mlock(mutex_);        int size = queue_.size();        mlock.unlock();        return size;    }

对front()的调用会等到它有一个元素并锁定底层队列,因此一次只有一个线程可以访问它.

总结

以上是内存溢出为你收集整理的c – 为什么std :: queue不是线程安全的?全部内容,希望文章能够帮你解决c – 为什么std :: queue不是线程安全的?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1218416.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存