Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::queue pop push thread safety

Basically my question is: is it safe to call front+pop and push from two thread without synchronization? 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?

like image 713
Vladp Avatar asked Dec 25 '22 01:12

Vladp


1 Answers

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.

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. 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.

like image 115
Anteru Avatar answered Feb 10 '23 18:02

Anteru