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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With