Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is calling size() on a std container thread safe?

I have a buffer using a std list container.

A worker is pushing elements on one side, and another thread is popping from the other side. Both these threads are using a mutex before accessing the container.

As a way to see the performance, I need to query the container for its size. But querying for size using a mutex seem like overkill, if not necessary.

Question is, is it necessary?

Documentation says on calling size() (under section Data Races: No contained elements are accessed: concurrently accessing or modifying them is safe.

like image 602
Totte Karlsson Avatar asked Sep 20 '19 20:09

Totte Karlsson


People also ask

Is Size () thread safe?

No, they're not thread-safe. The standard containers are simply not thread-safe, period. There is however a limited amount of thread safety: If every thread accesses a different element, and no element is accessed by two distinct threads at any given time, then that's fine.

Is STD vector size thread safe?

Yes, you are right. I obviously misunderstood that sentence in the documentation: "No contained elements are accessed: concurrently accessing or modifying them is safe." It probably only means that size() is thread-safe against a concurrent modification of the elements already in the container.

Is emplace back thread safe?

emplace_back changes things, operator[] read them (read a least a pointer to the data). These operations don't guaranteed to be atomic. Therefore, it is not thread safe.

Is std :: map thread safe?

It isn't thread safe, insert from two threads and you can end up in an inconstant state.


1 Answers

Question is, is it necessary?

Yes. You could be adding an element into the list while querying it's size and that is undefined behavior.

The rule is if you more than one thread accessing a shared object, and at least one of them writes to said object, you must have synchronization. If you do not you have a data race and that is undefined behavior.


Per your edit:

No contained elements are accessed: concurrently accessing or modifying them is safe. means that the elements of the list are not accessed or mutated. That means you can call size() and not worry about it modifying any element in the list. Right before that it has The container is accessed. It is that access that is not thread safe. If you were adding an element to the list when you called size the the value you get is undefined.

like image 163
NathanOliver Avatar answered Sep 28 '22 05:09

NathanOliver