C++ STL map/vector of vectors and thread safety
I was wondering whether following code would be considered thread-safe. I think it should be, but am not too familiar with what goes on under the hood.
Basically, I have this function in class Foo that will be called on the main thread and takes a vector as an anrgument, ie,
void Foo::func( vector<int> v)
In Foo, I also have a private member,
vector< vector<int> > vecOfVec;
Within func
, I'll simply push back any new v
onto vecOfVec
and check for v
's size. If v
is smaller than its expected size, I'd like to kick off another thread that fills up v
with some known, predetermined values, like so
void Foo::func( vector<int> v)
{
int size = v.size();
int index = vecOfVec.size();
vecOfVec.push_back(v);
if (size < 1000)
{
boost::thread t( boost::bind( &Foo::PushBackZeros, this, vecOfVec, index) );
}
}
Foo::PushBackZeros
would, as its name sugge开发者_运维百科sts simply fill up the vector at 'vecOfVec[index]' with zeros until its size grows to 1000;
Now, I don't see any concurrent read or write operations here on any of the elements of vecOfVec
. Obviously, there is a chance of concurrent operations on the entire object, but there will never be concurrencies on a particular element of vecOfVec
.
Could someone explain as to whether the above would be considered thread-safe? Would the same extent to STL maps also? If not, please explain. Cheers!
I think, that this is not thread-safe. What happens, if one thread pushes a new element onto the vector, which causes the vector's internal memory area to need to grow? The pushing thread might exchange the memory for a larger buffer, which can cause threads reading in parallel to this operation to suddenly read from invalid(ated) memory. Or threads seeing random values in certain slots, just because they read concurrently to the code which copies the contents of the vector from the old memory location to the new one.
If your Foo::PushBackZeros
has the same signature as Foo::func( vector<int> v)
, then it will be thread safe, since you pass a copy of the array to that function. So there will be no concurrent access.
vecOfVec is being passed by value because boost::bind requires you to put a boost::ref around a reference parameter.
So likely thread-safe but not doing what you think it is.
I am not sure why you need to pass that parameter in, as it is already in "this".
To answer the original question though for what you want to do:
- If vecOfVecs may be resized then any of its members could be invalidated so it would not be thread-safe.
- Pushing members into one of the inner vectors will not invalidate any other member vectors, so you could have different threads populating different vector members at the same time as long as they are all already there.
- If you "reserve" ahead then you can push_back more members into your vector until that capacity is reached and it won't invalidate existing members.
精彩评论