简体   繁体   中英

It is safe to push_back on a 2D vector on threads?

Lets say I have a 2D array and this function:

void addVec(std::vector<std::vector<short> >& arr, size_t idx){ 
   arr[idx].push_back(idx);
}

std::vector<std::vector<short> > arr(2);
boost::threads th1(addVec, boost::ref(arr), 0);
boost::threads th2(addVec, booost::ref(arr), 1);
th1.join();
th2.join();

By now I should have arr[0][0] = 0; and arr[1][0] = 1; The questions is if this is safe? Internally the threads should add values to different parts of vector memory, and because it is constructed at the beginning of size 2 only the internal vectors get resized, witch have thread exclusive access.

This should be safe since each thread accessing a separate vector. If however you do anything that might cause arr to resize, then all bets are off...

I would suggest that you take a step back and consider what your goal is, before you continue down the path you are on.

First off, why do you want to parallelize your code? I assume you want your program to run faster. That means

  1. You should start by writing a working sequential implementation.
  2. You should profile and tune that implementation.
  3. If (and only if) your program is still too slow for your purpose you should parallelize it if:
    1. A large part of the program can be parallelized (check out Amdahl's law ).
    2. Your sequential implementation makes good use of the cache . The cache is very likely to be a bottleneck even for sequential code, so if your code isn't cache-efficient it will probably be slower when you parallelize it.

Points 1. and 2. is probably where you should be devoting your time. Odds are that a highly tuned sequential implementation is more than adequate for your needs and it will be much cheaper/easier/faster to develop and maintain.

If you do decide to parallelize your code, you should take a look at OpenMP . Threads are probably one of the worst ways to write parallel programs known to man. You may think that OpenMP's runtime system is too slow for you but again, you should take a step back and think about why.

If your algorithm requires a lot of locks and barriers, you can get a minor speedup by using faster locks and barriers. If you improve your algorithm to use fewer locks and barriers, you can achieve a much larger speedup.

这是安全的,尽管从设计的角度来看,只给每个线程提供其内部矢量会更安全,所以将来发生不安全行为的可能性较小

Yes, it is safe in your use case, because you don't modify the shared data. However, I would prefer to pass the reference to the std::vector<short> to each thread to simplify the usage:

void addVec(std::vector<short> & arr)
{ 
   arr.push_back(some_data);
}

std::vector<std::vector<short> > arr(2);
boost::threads th1(addVec, boost::ref(arr[0]));
boost::threads th2(addVec, booost::ref(arr[1]));
th1.join();
th2.join();

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