听说有人说var++、++var等语句不是线程安全的,于是写了一个应用程序来测试一下。代码如下:
unsigned long gCounter = 0;
const unsigned long WORKS = 1048576; // pow(2, 20)
const unsigned long MAX_THREADS = 100;
const unsigned long WORKER_THREADS = 2;
unsigned long GetCounter(){
return gCounter++;
}
void *WorkerThread(void *){
unsigned long items = 0;
do {
GetCounter();
items++;
} while(items < WORKS);
printf("Exiting thread: %lu\n", pthread_self());
return NULL;
}
int main(int argc, char* argv[]){
pthread_t workers[MAX_THREADS];
//create two threads
for (int i = 0; i < WORKER_THREADS; i++){
pthread_create(&workers[i], NULL, WorkerThread, NULL);
}
//wait for above threads to exit
for (int i = 0; i < WORKER_THREADS; i++){
pthread_join(workers[i], NULL);
}
assert( gCounter == (WORKER_THREADS * WORKS));
return 0;
}
如果后增量操作不是线程安全的,那么上面的测试应用程序有时会失败(可能会成功)。但令我惊讶的是,在我们的服务器上运行时,它总是在 200 次测试中成功,而在我的 PC 上它从未成功。
为什么会这样?为什么上面的应用程序在我们的服务器上一直成功?以下是有关服务器和我的 PC 的信息:
Server machine:
System: Redhat 3.4.2 - 6.FC3 Kernel: LINUX.2.6.10
GCC Version: 3.4.2 20041017
CPU: AMD Opteron Processor 144 X86_64
My PC:
System: ubuntu 3.2.0-40-generic Kernel: LINUX.3.4
GCC Version: 4.6.3 (Ubuntu/Linaro )
CPU: Intel(R) Pentium(R) Dual CPU T2370
Build Command (both are the same, turn off optimization)
g++ -O0 -o test test.cpp -lpthread
更新
今天发现CPU是AMD Opteron 144的服务器是单cpu单核机,可能这就是为什么这个测试应用在上面从来不失败的原因。据我了解,单cpu单核机器不支持真正的线程并行,线程以非常快的速度有序运行,它们似乎并行运行,但实际上不是,一些线程同步问题不是在这种机器上很容易发生。
最佳答案
您的代码具有未定义的行为,因为它包含数据竞争。
[intro.multithread]/21
The execution of a program contains a data race if it contains two conflicting actions in dierent threads, at least one of which is not atomic, and neither happens before the other. Any such data race results in undefined behavior.
[intro.multithread]/4
Two expression evaluations conflict if one of them modifies a memory location (1.7) and the other one accesses or modifies the same memory location.
由于您的代码具有未定义的行为,因此您不能依赖它具有任何特定行为。不要惊讶它总是在一个平台上“有效”而在另一个平台上永远无效。
[defns.undefined]
Undefined Behavior: Behavior for which this International Standard imposes no requirements.
关于c++ - 为什么这个测试应用程序在不同的机器上给出不同的结果? (关于后增量和线程安全),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16847929/