【发布时间】:2019-01-19 17:04:36
【问题描述】:
我有以下代码,来自一本书,在 Ubuntu 18.4 上编译,使用 Eclipse -O0 -g3
#include <pthread.h>
#include <stdio.h>
void *myThread( void *arg )
{
printf( "Thread %d started\n", (int)arg );
pthread_exit( arg );
}
#define MAX_THREADS 5
int main()
{
volatile int i;
int status;
int ret;
pthread_t threadIds[MAX_THREADS];
for (i = 0 ; i < MAX_THREADS ; i++) {
ret = pthread_create( &threadIds[i], NULL, myThread, (void *)i );
if (ret != 0) {
printf( "Error creating thread %d\n", (int)threadIds[i] );
}
}
for (i = 0 ; i < MAX_THREADS ; i++) {
printf("----------- i = %d\n",i);
ret = pthread_join( threadIds[i], (void **)&status );
if (ret != 0) {
printf( "Error joining thread %d\n", (int)threadIds[i] );
} else {
printf( "Status = %d\n", status );
}
}
return 0;
}
这段代码正常工作并产生了输出
----------- i = 0
Thread 3 started
Thread 0 started
Status = 0
----------- i = 1
Thread 2 started
Thread 1 started
Status = 1
----------- i = 2
Status = 2
----------- i = 3
Status = 3
----------- i = 4
Thread 4 started
Status = 4
但是,如果变量 i 声明处的 volatile 关键字被忽略,则会产生以下输出:
Thread 1 started
Thread 0 started
Thread 2 started
Thread 3 started
----------- i = 0
Status = 0
----------- i = 1
Status = 1
----------- i = 1
Error joining thread -947054848
----------- i = 2
Status = 2
----------- i = 1
Error joining thread -947054848
----------- i = 2
Error joining thread -955447552
----------- i = 3
Status = 3
----------- i = 1
Error joining thread -947054848
----------- i = 2
Error joining thread -955447552
----------- i = 3
Error joining thread -963840256
----------- i = 4
Thread 4 started
Status = 4
----------- i = 1
Error joining thread -947054848
----------- i = 2
Error joining thread -955447552
----------- i = 3
Error joining thread -963840256
----------- i = 4
Error joining thread -1073744128
请帮助我确定导致此问题的可能原因。
【问题讨论】:
-
@Alerra 你错了。 volatile 不保证一致性,锁定访问的原子性。只说该变量容易产生副作用,即强制在使用前读取并在更改后存储,仅此而已
-
(void *)i,不应该是(void*)&i吗? -
在从
pthread_join()返回错误时,打印值或ret(错误号)比打印线程ID 提供更多信息。然而,这并不能解释出了什么问题。 -
@DanFarrell:将
i的地址传递给pthread_create()会导致各种同步问题——不同的线程不一定会看到i中当时的值当pthread_create()被调用时。 -
如果代码确实是一本书的逐字记录,也许你应该告诉我们它的名字——然后然后烧掉它。
标签: c linux multithreading