Are read from and writing to vector thread-safe op

2019-08-04 06:05发布

问题:

This question already has an answer here:

  • std::vector, thread-safety, multi-threading 3 answers

I have a below code that gives segmentation fault sometime?

vector<int> myvector;
void function1()
{
    for(int i = 0;i<10;i++)
    {
        cout<<"writer thread:"<<i<<endl;
        myvector.push_back(i);
    }
}
void function2()
{
    for(int i = 0;i<10;i++)
    {
        cout<<"reader thread:";
        cout<<myvector[i]<<endl;
    }
}
int main()
{

    thread t1(function1);
    thread t2(function2);

    t1.join();
    t2.join();
}

I am little confused with the thread safe rules/guarantees on containers in general and vectors in particular. I was asked this question in an interview and failed to put in words why it write in on thread and write in other thread is not thread-safe operation.

in the below link for push_back of vectors I see "Otherwise, no existing element is accessed, and concurrently accessing or modifying them is safe" under Data Race section. How does this statement justify that vector write operation is not thread-safe?

http://www.cplusplus.com/reference/vector/vector/push_back/

回答1:

From Scott Meyers, Effective STL, Item 12: "Have realistic expectations about the thread safety of STL containers".

  • Multiple readers are safe. Multiple threads may simultaneously read the contents of a single container, and this will work correctly. Naturally, there must not be any writers acting on the container during the reads.

  • Multiple writers to different containers are safe. Multiple threads may simultaneously write to different containers.

That's all, and let me make clear that this is what you can hope for, not what you can expect.

I think I don't have to provide any additional interpretation here :)



回答2:

That is as unsafe as it gets. Imagine you just run the second thread first, and only than (after it is completed) you start executing the first one. What do you think will your code do?

So even if std::vector was super thread-safe for concurrent access (it is not) the code still would be very wrong.



回答3:

No, std::vector<> is not thread-safe how you are using it. It is only thread-safe in the following cases:

  1. All threads are only reading from the vector
  2. If one thread writes to the vector, there are no concurrent reading operations.

The Segmentation Fault happens when function2 is running earlier/faster then function1. ``function1I would for example access myvector[4] which wasn't push'ed to the vector. In this case you will get an access-out-of-bonds error and, depending on what the rest of your system is doing, this could lead to reading wrong data or a segmentation fault.



回答4:

The rule is: If you have a shared object accessed between threads, and at least one of those threads is a writer, then you need synchronization. Without that you have data race which is undefined behavior.

In your case since you are reading from the vector while you are writing to it, it is definitely not thread safe.