简体   繁体   中英

std::vector natural thread safe while iteration

Assuming, I have std::vector and two threads.

First thread is processing erase function while second thread is in for-loop

Is this situation a thread-safe?

Would second thread keep running or throwing an exception?

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

int main()
{
    std::vector<int> intContainer;

    for ( int index = 0; index <= 100000; ++index){
        intContainer.push_back(index);
    }

    std::thread t1([&](){
        while ( 1 ){
            intContainer.erase( std::find(intContainer.begin(), intContainer.end(), random(1, 100000) ) );
            std::this_thread::sleep_for(std::chrono::milliseconds(500));
        }
    });

    std::thread t2([&] (){
        for ( auto& val : intContainer ){
            std::cout << val << std::endl;
        }   
    });

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

    return 0;
}

It is thread-unsafe, but also undefined behavior.

It is thread-unsafe because you are changing elements (and the vector itself) while you are iterating through it.

It is undefined behavior because of the above point (races), but also because you are erasing elements basically anywhere in the vector, which means you are effectively invalidating all iterators to it (which you are using to iterate in the other thread). So even if this was a single-threaded program (eg using fibers), you would still have UB.


Note that exceptions won't be thrown because something isn't thread-safe. That does not mean, of course, that errors (be it corruption, crashes, etc.) won't happen -- they will, with most certainty.

In addition, note that the threads (neither of them) will "stop running" either. They will continue without knowing they are messing up everything. The point is that there is no way for them to know.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM