Threading questions

I have some situations in a multithreaded app that I'm not sure about. I was hoping someone here might be able to answer these questions.

I know on older systems race conditions can be big trouble on older computers (I've written NES/SNES emulators, so I know that very bad things can happen when different hardware attempts to access the same memory at the same time). However I would imagine that more modern computers are designed to cope with them better. So I'm wondering just how safe I need to be to guard against race conditions.

For the following examples, assume worst case scenarios (multi-core system, truely simultaneous accesses):

--------------------------------
1) A shared variable is read by several threads, but is not written by any threads. Assuming the state of this variable never changes, is it safe to assume that all threads reading this variable will properly receive its contents? Or is it possible that a thread might receive garbage/open bus if it attempts to read while another thread is reading it?

Basically: do simultaneous read-only operations need to be guarded by mutexes?


--------------------------------
2) A shared variable is written by only 1 thread, but is read by several threads. Assuming this is a simple state change (assignment of a simple, basic data type -- no complex computations), will it be guaranteed that the reading threads will receive either the old or new value? Example:

1
2
3
4
5
6
7
8
9
10
11
int shared = 0;  // 0 initially

void WritingThread()
{
  shared = 12345;
}

void ReadingThread()
{
  int foo = shared;
}


Running this code, is it safe to assume that 'foo' will be either 0 or 12345? Or is another value possible due to a bus conflict / race condition / partially written value?


Thanks in advance for any help!
1) It's safe, don't need mutexes.

2) this code is NOT multithread safe,
You'd better use of interlocking function(All the threads in the same process)
or mutexes (Threads in different processes) in WritingThread ...
1 and 2) If it's a variable, then there's no problem if only one thread updates it while all the others just read it, since it can be read from and written to in a single operation. A thread is guaranteed to read something at any time. It will be either the old or the new value, but since the operation is atomic, it's impossible to read some invalid middle value. Think of it as a hardware-enforced mutual exclusion.
If it's an object or anything more complex than a variable (e.g. an array), then you better put a mutex lock around it.

EDIT: Disregard binaryboy's comment. That code in particular is safe, provided that only one thread can call WritingThread().
Last edited on
Yes, helios is right. If only one thread can call WrithingThread(), that code is exactly safe.

Besides, "shared = 12345;" maybe is a atomic operation on some platform.
But it's uncertain.

So, you'd better use of Explicit atomic operation or mutexes if more than one thread can call WritingThread()...

:P
Excellent, this is great news to hear. Thanks to both of you.

I assume that #2 is only safe because the data type (here, int) can be fully written in one write operation (therefore making it atomic). I'm going to go out on a limb here and say that if I changed that example to make it a long long it would no longer be safe on 32-bit systems (since it would require two writes -- one for the high dword and one for the low)

And yeah -- in any situations where there would be simultaneous writes, I would definately use a mutex.

Thanks a bunch!
Topic archived. No new replies allowed.