简体   繁体   English

std :: queue pop push thread safety

[英]std::queue pop push thread safety

Basically my question is: is it safe to call front+pop and push from two thread without synchronization? 基本上我的问题是:调用front + pop并从两个线程推送而不同步是否安全? I've read about this and never found a clear answer. 我已经读过这个,但从未找到明确的答案。 People are saying you should use mutex, but some are hinting you can use two different mutexes for push and for pop. 人们说你应该使用互斥锁,但有些人暗示你可以使用两种不同的互斥锁进行推送和弹出。 Is it true? 这是真的吗?

Does this code has undefined behavior? 此代码是否具有未定义的行为?

std::queue<int> queue;

int pop()
{
    int x = queue.front();
    queue.pop();
    return x;
}

void push(int x)
{
    queue.push(x);
}

int main()
{
    queue.push(1);
    std::thread t1(pop);
    std::thread t2(push);

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

I would say it's undefined behavior, but you can design a pop push safe queue, so why isn't std::queue is like that? 我会说这是未定义的行为,但你可以设计一个pop push safe队列,那么为什么std :: queue不是那样的呢?

No, it's not. 不,这不对。 The standard containers are not thread-safe -- you can't mutate them from two threads. 标准容器不是线程安全的 - 你不能从两个线程中改变它们。 You will have to use a mutex, or a lock-free queue. 您必须使用互斥锁或无锁队列。 The problem is that the std::queue has to be able to work with objects like std::string , which cannot be atomically moved or constructed, and the std::queue also has to support arbitrary sizes. 问题是std::queue必须能够处理像std::string这样的对象,这些对象不能被原子地移动或构造,并且std::queue也必须支持任意大小。

Most lock-free queues only work with machine-word size types and a fixed maximum size. 大多数无锁队列仅适用于机器字大小类型和固定的最大大小。 If you need the flexibility of std::queue and thread-safety, you'll have to manually use a mutex. 如果您需要std::queue和thread-safety的灵活性,则必须手动使用互斥锁。 Adding the mutex to the default implementation would be also extremely wasteful, as now suddenly every application would get thread safety even if it doesn't need it. 将互斥锁添加到默认实现中也会非常浪费,因为现在突然每个应用程序都会获得线程安全,即使它不需要它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM