std :: queue pop push thread safety

时间:2014-12-15 07:39:29

标签: c++ multithreading thread-safety queue

基本上我的问题是:调用front + pop并从两个线程推送而不同步是否安全? 我已经读过这个,但从未找到明确的答案。人们说你应该使用互斥锁,但有些人暗示你可以使用两种不同的互斥锁进行推送和弹出。这是真的吗?

此代码是否有未定义的行为?

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();
}

我会说它的未定义行为,但你可以设计一个pop push safe队列,那么为什么stn :: queue就是这样?

1 个答案:

答案 0 :(得分:7)

不,不是。标准容器不是线程安全的 - 你不能从两个线程中改变它们。您必须使用互斥锁或无锁队列。问题是std::queue必须能够处理std::string之类的对象,这些对象无法原子地移动或构造,std::queue也必须支持任意大小。

大多数无锁队列仅适用于机器字大小类型和固定的最大大小。如果您需要std::queue和线程安全的灵活性,则必须手动使用互斥锁。将互斥锁添加到默认实现中也会非常浪费,因为现在突然每个应用程序都会获得线程安全,即使它不需要它。