views:

167

answers:

7

Lets say I have a vector of int which I've prefilled with 100 elements with a value of 0.

Then I create 2 threads and tell the first thread to fill elements 0 to 49 with numbers, then tell thread 2 to fill elements 50 to 99 with numbers. Can this be done? Otherwise, what's the best way of achieving this?

Thanks

A: 

What you describe is quite possible, and should word just fine.

Note, however, that the threads will need to work on a std::vector*, i.e. a pointer to the original vector---and you probably should allocate the vector on the heap, rather than the stack. If you pass the vector directly, the copy constructor will be invoked and create a separate copy of the data on each thread.

There are also lots of more subtle ways to get this wrong, as always with multithreaded programming. But in principle what you described will work well.

JSBangs
A: 

vector is not thread safe. You need to guard the vector between threads. In your case it depends on vector implementation. If the vector internal data is accessed\modified from different threads, it purely depends on vector impl.

aJ
assuming he's using 'vector' and not a vector (c++/c) - what is the danger in accessing disparate locations?
KevinDTimm
I assume its c++ vector.
aJ
+3  A: 

Yes, this should be fine. As long as you can guarantee that different threads won't modify the same memory location, there's no problem.

tzaman
I think this should actually read "...as long as you guarantee that _no thread modifies a memory location that another thread accesses_, be it reading or writing access."
sbi
It should be noted that even though it should work, it will most likely be very slow due to mutual cache invalidation.
Michael Aaron Safyan
+1  A: 

There is no reason why this cannot be done. But, as soon as you start mixing accesses (both threads accessing the same element) it becomes far more challenging.

KevinDTimm
A: 

With arrays it can be done for sure (the threads do not access the same memory area); but as already noted, if you use the std::vector class, the result may depend on how it is implemented. Indeed I don't see how the implementation of [] on the vector class can be thread unsafe (provided the threads try to access different "indexes"), but it could be. The solution is: stick to the use of an array, or control the access to the vector using a semaphore or similar.

ShinTakezou
+3  A: 

Yes, for most implementations of vector, this should be ok to do. That said, this will have very poor performance on most systems, unless you have a very large number of elements and you are accessing elements that are far apart from each other so that they don't live on the same cache line... otherwise, on many systems, the two threads will invalidate each other's caches back-and-forth (if you are frequently reading/writing to those elements), leading to lots of cache misses in both threads.

Michael Aaron Safyan
I believe that the Windows/Linux implementation of threads does not invalidate cache, since different threads are working on the same virtual memory, unlike different processes.
Oak
@Oak, this has nothing to do with the OS. This is implemented by the processor cache. On a system such as x86 with coherent cache, writing to a memory address that has been cached by multiple cores will require an issuing of a read-exclusive (invalidation) operation in order to maintain cache coherence.
Michael Aaron Safyan
@Michael: thanks for the explanation.
Oak
+1  A: 

The fact that "vector is not thread-safe" doesn't mean anything. There's no problem with doing this.

Also you don't have to allocate your vector on heap (as one of the answers suggested). You just have to ensure that the lifetime of your vector covers the lifetime of your threads (more precisely - where those threads access the vector).

And, of course, since you want your both threads to work on the same vector - they must receive it from somewhere by pointer/reference rather than by value.

There's also absolutely no problem to access the same element of the array from within different threads. You should know however that your thread is not the only one that accesses it, and treat it respectively.

In simple words - there's no problem to access an array from within different threads. Accessing the same element from different thread is like accessing a single variable from different thread - same precautions/consequences.

The only situation you have to worry about is when new elements are added, which is impossible in your case.

valdo