2607
2607

Reputation: 4115

std::vector, thread-safety, multi-threading

I am using std::vector as shared data in a multi-threaded application. I encapsulate the thread inside a class, e.g.,

class ABC {
public:
    double a, b, c;
};

boost::mutex mutex1;

class XYZ {
public:
    XYZ(vector<ABC> & pVector) {
        ptrVector = &pVector;
        m_thread = boost::thread(&XYZ::Start, this);
    }
    ~XYZ() {}
    void Start();
public:
    vector<ABC> * ptrVector;
    boost::thread m_thread;  
};    

void XYZ::Start() {
    try {
        while(1) {
            boost::this_thread::interruption_point();
            for (unsigned int i=0; i<ptrVector->size(); i++) {
                {
                    boost::mutex::scoped_lock lock(mutex1);
                    ptrVector->at(i).a = double(rand())/10000;  
                    ptrVector->at(i).b = double(rand())/10000;
                    ptrVector->at(i).c = double(rand())/10000;
                }
            }
        }
    }
    catch(boost::thread_interrupted) {}
    catch(std::exception) {} 
}

When I close the application, sometimes, in the debug, there will be 2 error messages, sometimes there will be no error messages. I often heard people talking about std::vector being not thread-safe, is this one of the cases? I am using Visual Studio 2008, boost thread, the size of the vector is fixed. Can anyone also offer some advice on how to use std::vector in a multi-threaded application.

  1. First-chance exception at 0x7688b9bc in ETP.exe: Microsoft C++ exception: std::out_of_range at memory location 0x02d8f7bc..
  2. First-chance exception at 0x00e916e0 in ETP.exe: 0xC0000005: Access violation reading location 0x00000008.
  3. Second Chance Assertion Failed: File c:\program files (x86)\microsoft visual studio 9.0\vc\include\vector, Line Second Chance Assertion Failed: File c:\program files (x86)\microsoft visual studio 9.0\vc\include\vector98

Thanks.

Upvotes: 9

Views: 29386

Answers (4)

Graham Asher
Graham Asher

Reputation: 1780

To add to what has been said above by Dietmar Kühl, when he states that thread safety

... applies to vector structure itself. Accesses to contained object are bound to whatever rules are imposed on them.

it is indeed possible to access the contiguous area of memory allocated by a vector from multiple writing threads, as long as each thread accesses different elements of the vector. For example, to populate an array of ten thousand elements from ten threads, first set the size of the vector to ten thousand, then pass a pointer to the block of memory starting at element 0, 1000, 2000, ... etc., to each thread, which can happily write to its block of a thousand elements. That will work correctly as long as no thread calls any function that could result in a reallocation of the vector's storage.

Upvotes: 0

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153792

Actually, it is absolutely pointless to state X is or is not thread-safe! You need to qualify for what kind of uses. For example, hardly any class will be "thread-safe" when it is somehow used in one thread and destroyed in another.

That said, the statement that std::vector<T> is not thread- safe, independent of how often it is repeated, is wrong. However, it seems most people neither understand nor appreciate the thread-safety guarantees given. std::vector<T> is thread-safe in the following sense:

  • You can read a vector object from multiple threads simultaneously.
  • If there is one thread changing a vector object, there shall be neither concurrent readers or writers.
  • Accesses to a vector object don't interfere with other vector objects.

This applies to vector structure itself. Accesses to contained object are bound to whatever rules are imposed on them. These are apparently not the thread-safety guarantees many people have in mind but anything stronger won't work with the container interface.

Upvotes: 28

screig
screig

Reputation: 627

Maybe you could use this instead?

concurrent_vector... from the Intel Threading Building Blocks

https://software.intel.com/en-us/node/467758

Upvotes: 0

Clark Gaebel
Clark Gaebel

Reputation: 17938

You call ptrVector->size() without locking it first. This could easily be the cause of your problems. Make sure to lock your vector before any reads or writes.

Upvotes: 4

Related Questions