我正在学习C线程概念,我在下面编写了简单的代码。现在,当我编译并运行它时,我会得到意外打印的随机行为。
#include <pthread.h>
#include <stdio.h>
void * func_threadName(void * i) {
int *x=(int *)i;
printf("I'm thread : %d\n",*x);
return NULL;
}
main()
{
int iter;
printf("testing multithreading....\n");
pthread_t thread_arr[3];
for (iter=0;iter<3;iter++)
{
pthread_create(&thread_arr[iter],NULL,func_threadName,&iter);
}
for (iter=0;iter<3;iter++)
{
pthread_join(thread_arr[iter],NULL);
}
}
它不可预测地打印如下:
diwakar@diwakar-VPCEH25EN:~/Documents/my_C_codes$ ./thread_test.o
testing multithreading....
I'm thread : 0
I'm thread : 0
I'm thread : 0
diwakar@diwakar-VPCEH25EN:~/Documents/my_C_codes$ ./thread_test.o
testing multithreading....
I'm thread : 0
I'm thread : 2
I'm thread : 1
diwakar@diwakar-VPCEH25EN:~/Documents/my_C_codes$ ./thread_test.o
testing multithreading....
I'm thread : 2
I'm thread : 2
I'm thread : 0
但是当我在创建线程后进行如下所示的微小更改时,它会完美地工作并按顺序打印。
pthread_create(&thread_arr[iter],NULL,func_threadName,&iter);
sleep(1);
现在每次输出都是这样的:
diwakar@diwakar-VPCEH25EN:~/Documents/my_C_codes$ ./thread_test.o
testing multithreading....
I'm thread : 0
I'm thread : 1
I'm thread : 2
diwakar@diwakar-VPCEH25EN:~/Documents/my_C_codes$ ./thread_test.o
testing multithreading....
I'm thread : 0
I'm thread : 1
I'm thread : 2
diwakar@diwakar-VPCEH25EN:~/Documents/my_C_codes$ ./thread_test.o
testing multithreading....
I'm thread : 0
I'm thread : 1
I'm thread : 2
我想了解在第一种情况下,显示的是不可预测的行为,因为所有线程共享相同的内存空间,因此在一个线程终止之前,其他线程使用相同的i值?欢迎任何其他信息。
答案 0 :(得分:4)
当线程要运行时,你无法准确判断,因此主线程可以继续,从而在其循环中更改计数器。因为该循环计数器是一个指针,所有线程都有相同的指针指向完全相同的变量。您还可以在第二个循环中使用相同的变量,因此可以在线程的生命周期内对其进行两次修改。
将“按原样”传递数字会更好(尽管更“黑客”):
pthread_create(&thread_arr[iter], NULL, func_threadName, (void *) iter);
然后在线程函数中得到它:
int x = (int) i;
答案 1 :(得分:0)
每个线程都应该看到不同的int
对象,因此您必须使用第二个数组来管理它。
void * func_threadName(void * i) {
int *x= i;
printf("I'm thread : %d\n",*x);
return NULL;
}
int main(void) {
printf("testing multithreading....\n");
pthread_t thread_arr[3];
int iter_id[3];
for (int iter=0; iter<3; iter++) {
iter_id[iter] = iter;
pthread_create(&thread_arr[iter], NULL, func_threadName, &iter_id[iter]);
}
for (iter=0;iter<3;iter++) {
pthread_join(thread_arr[iter],NULL);
}
}
同样在C
void*
指针main
(void)
答案 2 :(得分:0)
代码的问题在于您传递变量的地址而不是值。因此,所有线程都引用该地址存储的“相同”值。正如Joachim所提到的,这意味着值可能不会足够快地变化,以便新创建的线程获得它。当使用'sleep'时,主线程允许处理器执行其他指令,因此在创建新线程之前更改迭代变量的值。总而言之,您需要传递变量的值而不是Joachim示例中的地址。