C ++ Multithreading with global variables

Does anyone know if a primitive global variable is thread safe or not?

// global variable int count = 0; void thread1() { count++; } void thread2() { count--; if (count == 0) print("Stuff thing"); } 

Can I do this without lock protection for count ?

Thanks.

+4
source share
6 answers

This is not thread safe. You have a race here. The reason for this is that count++ not necessarily atomic (meaning not a single-processor operation). The value is first loaded, then incremented, and then written back. Between each of these steps, another thread can also change the value.

+6
source

No no. This may be, depending on the implementation, compilation time parameters and even the moon phase.

But the standard does not require something to be thread safe, especially because there is nothing about streaming in the current standard.

See also here for a more detailed analysis of these kinds of problems.

If you are using an environment in which threads are supported, you can use a mutex: for example, consider pthread_mutex_* calls under POSIX threads.

If you code C ++ 0x / C ++ 11, use either a mutex or one of the atomic operations described in this standard.

+3
source

This is a global variable, and therefore several threads can participate in changing it. It is not thread safe.

Use mutex lock.

0
source

In general, no, you cannot get away from this. In your trivial example, this may happen, but it is not reliable.

0
source

It will be thread safe only if you have 1 c ++ processor and - atomic operations on your PC.

If you want to make it thread safe, this is the way for Windows:

 LONG volatile count = 0; void Thread1() { ::InterlockedIncrement( &count ); } void Thread2() { if(::InterlockedDecrement( &count ) == 0 ) { printf("Stuf"); } }
LONG volatile count = 0; void Thread1() { ::InterlockedIncrement( &count ); } void Thread2() { if(::InterlockedDecrement( &count ) == 0 ) { printf("Stuf"); } } 
0
source

You need two things to safely use an object simultaneously with two or more threads: atomicity of operations and guarantees of order.

Some people will pretend that on some platforms what you are trying to do here is safe, for example, operations on any type of int means that these platforms are atomic (even incrementing or whatever). The problem is that you do not necessarily have an order guarantee. Therefore, while you want to know that this particular variable will be available at the same time, the compiler does not. (And the compiler is right to assume that this variable will be used only one thread at a time: you do not want each variable to be considered as potentially separated. The performance consequences would be terrible.)

Therefore, do not use primitive types in this way. You have no guarantees from the language, and even if some platforms have their own guarantees (for example, atomicity), you have no way to tell the compiler that the variable is shared with C ++. Either use compiler extensions for atomic types, C ++ 0x atomic types, or library solutions (e.g. mutexes). And do not let the name fool you: to be truly useful, the atomic type must provide guarantees of order along with the atomicity that comes with the name.

0
source

All Articles