这是我编写的一个简单程序。它在for循环中创建10个线程,每个线程打印i:
的值#include <stdio.h>
#include <pthread.h>
void* basic_function(void *num){
int cur_num = *(int*)num;
printf("Current thread number is :%d\n", cur_num);
return NULL;
}
int main(int argc, const char * argv[]) {
pthread_t thread_id [10];
void * exit_status[10];
for (int i = 0; i < 10; i++){
pthread_create(&thread_id[i], NULL, basic_function, &i);
printf("i is: %d\n", i);
}
for (int i = 0; i<10; i++){
pthread_join(thread_id[i], &exit_status[i]);
return 0;
}
我认为输出应该看起来像0到9之间的一些打印语句,顺序正确:
Current thread number is: 0
i is: 0
Current thread number is: 1
i is: 1
Current thread number is: 2
i is: 2
...
但相反,我的输出是:
i is: 0
i is: 1
i is: 2
i is: 3
i is: 4
i is: 5
Current thread number is: 6
Current thread number is: 6
i is: 6
Current thread number is: 6
Current thread number is: 6
Current thread number is: 6
Current thread number is: 6
Current thread number is: 6
i is: 7
Current thread number is: 7
i is: 8
Current thread number is: 9
Current thread number is: 9
i is: 9
为什么多次创建线程6?为什么有些线程没有创建?而且,为什么我在运行程序时总会获得不同的输出?
答案 0 :(得分:1)
因为传递给线程函数的参数指向同一个变量 - i
。
由于变量i
不断从main
函数更新,因此线程总是在运行时获取最新值,并且线程与{{1}并行执行} 方法。此外,一旦循环已经完成,线程可能会访问变量,在这种情况下,它可能是未定义的行为。
解决方案是在堆上分配main
的副本并将指针传递给副本。或者另一个更脏的解决方案是将i
转换为指针,作为参数传递,然后在线程转换回int。这依赖于int小于指针,这很常见,但在一些模糊的架构上可能不是真的(可能不是这种小数字的情况)。