views:

1151

answers:

3

I am writing code in VS2005 using its STL. I have one UI thread to read a vector, and a work thread to write to a vector. I use ::boost::shared_ptr as vector element.

vector<shared_ptr<Class>> vec;

but I find, if I manipulate the vec in both thread in the same time(I can guarantee they do not visit the same area, UI Thread always read the area that has the information)

vec.clear() seem can not release the resource. problem happend in shared_ptr, it can not release its resource.

What is the problem? Does it because when the vector reach its order capacity, it reallocates in memory, then the original part is invalidated.

As far as I know when reallocating, iterator will be invalid, why some problem also happened when I used vec[i]. //-----------------------------------------------

What kinds of lock is needed? I mean: If the vector's element is a shared_ptr, when a thread A get the point smart_p, the other thread B will wait till A finishes the operation on smart_p right? Or just simply add lock when thread is trying to read the point, when the read opeation is finished, thread B can continu to do something.

+3  A: 

When you're accessing the same resource from more than one thread, locking is necessary. If you don't, you have all sorts of strange behaviour, like you're seeing.

Since you're using Boost, an easy way to use locking is to use the Boost.Thread library. The best kind of locks you can use for this scenario are reader/writer locks; they're called shared_mutex in Boost.Thread.

But yes, what you're seeing is essentially undefined behaviour, due to the lack of synchronisation between the threads. Hope this helps!

Edit to answer OP's second question: You should use a reader lock when reading the smart pointer out of the vector, and a writer lock when writing or adding an item to the vector (so, the mutex is for the vector only). If multiple threads will be accessing the pointed-to object (i.e., what the smart pointer points to), then separate locks should be set up for them. In that case, you're better off putting a mutex object in the object class as well.

Chris Jester-Young
A: 

Another alternative is to eliminate the locking altogether by ensuring that the vector is accessed in only one thread. For example, by having the worker thread send a message to the main thread with the element(s) to add to the vector.

John Dibling
I almost upped your answer, except that the OP might actually be trying to implement a message queue here. :-P Admittedly, it's probably better not to hand-roll one, but still.
Chris Jester-Young
A: 

It is possible to do simultaneous access to a list or array like this. However, std::vector is not a good choice because of its resize behavior. To do it right needs a fixed-size array, or special locking or copy-update behavior on resize. It also needs independent front and back pointers again with locking or atomic update.

Another answer mentioned message queues. A shared array as I described is a common and efficient way to implement those.

Zan Lynx