Hello All,

I was doing some multi-threaded programming using the new C++11. This thought came across my mind:
Is there any problem if some shared data is accessed by multiple cores on a CPU? Even if it is just a read.

Does this lead to some problem?
Could anyone please throw some light on this? Or perhaps some links on this?
Thanks!

Is there any problem if some shared data is accessed by multiple cores on a CPU?

Yes. There are several issues possible. Technically, if all you do, in all the threads, is to read the data, then there won't be any issues. Where things get ugly is if one thread modifies the value.

The mildest problem is that of a race condition. This is essentially a logical problem related to the fact that the output of your program depends on the relative timing between the read operations of one thread and the write operations of the other, which can be arbitrary (and non-deterministic). This can have effects ranging from a simple lag between the input and the output, to making certain input changes go unnoticed at the output, or even creating enough fluctuations at the output that it has stronger repercutions down the line (including wildly corrupt results).

Another problem is that sometimes, the write operation will be only partially accomplished when the thread is interrupted (by the OS scheduling), and if another thread reads the data at that point, it will read a completely corrupt value. This may sound like a very unlikely event, but when you are running a fast-paced loop, unlikely events become likely very quickly. This is generally solved with either a mutex (std::mutex in C++11), or atomic operations (std::atomic in C++11). A mutex is costly (blocking threads), but atomics (which are much less costly) should not be used for types that are too large or on which you are going to spend too much processing time on single read-writes.

Yet another problem is another kind of logical error. If two threads are writing to the same value, then they might negate each others actions. For example, if you are incrementing the same counter in both threads. Both threads might read the counter's value at the same time (i.e., the same value), they each do an increment on the value, and then they both write the value back to the cache / RAM. The result is that the value is only incremented once, when it really should have been incremented twice. Again, these issues are solved with mutexes or atomics, or other thread synchronization devices like semaphores, condition variables, futures / promises, memory barriers, etc.

There are other issues, with fancier names. But these are the basic ones, but, of course, things get increasingly difficult to deal with as the complexity of the program increases. A very important case is that of dynamic arrays and pointers. Imagine you have a std::vector object shared between two threads, and one resizes it while the other is iterating through it, it's like a pile of doodoo hitting a fan, as they say. At the very least, these types of things need to be protected by a mutex. The rule should be: when in doubt, protect with a mutex. Later on, if the mutexes become bottlenecks to the performance, you can selectively remove them, find ways around them, or use more efficient specialized alternatives (like spinlocks or lock-free algorithms).

With the use of thread synchronization devices like those listed above, there are a number of additional issues to worry about, in particular, dead-locks.

Here is a nice article introducing these concepts.

commented: thanks! +5

Thanks a lot for the reply mike_2000_17!

The links are very useful. Well, in my case, i am only doing reads and also ensuring there is no data shared between threads. So, it should be fine for me.

Also, i have another scenario where i have something like this:

void foo(List _list)
{
   // alter list
}

Now, i am sending the list by reference so that the data wouldn't be shared across threads. Right now, my list is small, and i can afford to do a pass by value. But, i would like to have a pass by reference for this.

I am planning to use a mutex for this purpose.(when the list would be altered)

Thanks!

I am planning to use a mutex for this purpose.(when the list would be altered)

That's definitely required here. You might want to check out my code snippet on lockable variables.

commented: thanks! +5
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.