Reputation: 1298
Anyone know whether 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 it this way without any lock protection for count
?
Thank you.
Upvotes: 5
Views: 13144
Reputation: 35449
You need two things to safely use an object concurrently by two threads or more: atomicity of operations and ordering guarantees.
Some people will pretend that on some platforms what you're attempting here is safe because e.g. operations on whatever type int
stands for those platforms are atomic (even incrementing or whatever). The problem with this is that you don't necessarily have ordering guarantees. So while you want and know that this particular variable is going to be accessed concurrently, the compiler doesn't. (And the compiler is right to assume that this variable is going to be used by only one thread at a time: you don't want every variable to be treated as being potentially shared. The performance consequences would be terrible.)
So don't use primitive types this way. You have no guarantees from the language and even if some platforms have their own guarantees (e.g. atomicity) you have no way of telling the compiler that the variable is shared with C++. Either use compiler extensions for atomic types, the C++0x atomic types, or library solutions (e.g. mutexes). And don't let the name mislead you: to be truly useful, an atomic type has to provide ordering guarantees along with the atomicity that comes with the name.
Upvotes: 1
Reputation: 856
It will be thread safe only if you have 1 CPU with ++ 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");
}
}
Upvotes: 1
Reputation: 8694
In general, no, you can't get away with that. In your trivial example case, it might happen to work but it's not reliable.
Upvotes: 0
Reputation: 881303
No, it's not. It may be, depending on the implementation, the compile-time options and even the phase of the moon.
But the standard doesn't mandate something is thread-safe, specifically because there's nothing about threading in the current standard.
See also here for a more detailed analysis of this sort of issue.
If you're using an environment where threads are supported, you can use a mutex: examine the pthread_mutex_*
calls under POSIX threads, for example.
If you're coding for C++0x/C++11, use either a mutex or one of the atomic operations detailed in that standard.
Upvotes: 3
Reputation: 206518
It is a Global variable and hence multiple threads can race to change it. It is not thread safe.
Use a mutex lock.
Upvotes: 0
Reputation: 76788
This is not threadsafe. You have a race-condition here. The reason for that is, that count++
is not necessarily atomic (means not a single processor operation). The value is first loaded, then incremented, and then written back. Between each of these steps, the other thread can also modify the value.
Upvotes: 8