3

Is there any advantage of declaring std::vector as thread_local? like

static unique_ptr<std::vector<ObjectA>> vecVariable;

as declaring std::vector as thread_local doesn't make its operations like pop_back() and erase() synchronized.

As in every STL container, If there is one thread modifying a container then there shall be no concurrent threads reading or writing the same container, so I can not do erase() and pop_back() on a vector object in a concurrent/multithreaded environment.

Even if I declare vector as thread_local, my code is crashing in one of the operations. I understand I may need to do these operations under lock, but I am just trying to understand when someone would define a std::vector as thread_local ?

Hayt
  • 5,210
  • 30
  • 37
user1174114
  • 178
  • 1
  • 19
  • Same time they'd define any variable as thread_local - when they each thread to have its own instance. – davmac Nov 11 '16 at 13:01

2 Answers2

6

thread_local is not meant to be used for synchronization. It is meant as a storage duration specifier ( http://en.cppreference.com/w/cpp/language/storage_duration)

Take this example:

#include <iostream>
#include <vector>
#include <thread>

thread_local std::vector<int> v;

void func()
{
  v.push_back(5);
  std::cout<< "t: "<< v.size() << std::endl;
}

int main() 
{
    v.push_back(3);
    v.push_back(5);
    std::thread t1(func);
    std::thread t2(func);
    std::cout<< "m: "<< v.size() << std::endl;
    t1.join();
    t2.join();
}

output:

m: 2
t: 1
t: 1

What thread_local does is create a different vector for each thread. In the example you can see v from the main thread has 2 elements, while the vector v in the other threads have only 1 element each.

What happens is, that when a new thread is created the program will also a create new vector for this thread only. The vector will also get destroyed when the thread ends.

Hayt
  • 5,210
  • 30
  • 37
4

thread_local causes an object to have thread storage, meaning that each thread will have its own separate instance of the object. It doesn't affect the thread-safety of the object in any way, as you seem to be suggesting that you think it should.

You would declare a vector variable, or any other variable, thread_local if you wanted each thread to have its own instance of the variable. If you want to able to access a single object concurrently, the solution is not to declare it thread_local, but instead to use a thread-safe data type or appropriate synchronisation primitives (eg by locking and unlocking a std::mutex).

davmac
  • 20,150
  • 1
  • 40
  • 68
  • @GillBates each thread _can_ access the copy belonging to the other threads, if it can obtain a reference to them by other means. That the name refers to different objects in different threads does not imply thread safety. – davmac Nov 11 '16 at 13:20
  • Of course they can through address passing or global references. I was talking about the case of using the name and only the name. – Hatted Rooster Nov 11 '16 at 13:21
  • As I said, there's no need to care about thread safety in the first place when accessing the elements in this vector through it's name, e.g. `vector[0]`. The keyword itself doesn't bring any synchronization but through proper use avoids data races between threads if threads don't rely on other threads to populate or modify this container. – Hatted Rooster Nov 11 '16 at 13:25
  • Indeed, I'll clear that comment up to avoid this misconception. – Hatted Rooster Nov 11 '16 at 13:26
  • @GillBates I think we can agree that there is no need to worry about thread-safety of an object accessed via a `thread_local` variable if it is accessed only via that variable, but I think it's a stretch to say that `thread_local` on a variable affects the thread safety of the object to which the variable declares; it _might_ make thread-safety a non-issue if the object is only accessed via the variable, as discussed above, but that is not the same as making it thread-safe - it's just making it so that it doesn't _need_ to be thread-safe. – davmac Nov 11 '16 at 13:32
  • Fair enough, let's keep it at that. – Hatted Rooster Nov 11 '16 at 13:32