这是我的代码。这很简单。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *func(void *arg)
{
printf("ID=%d\n", *(int*)arg);
pthread_exit(NULL);
}
int main()
{
pthread_t pt[4];
int i;
for (i = 0; i < 4; i++)
{
int temp = i;
pthread_create(&pt[i], NULL, func, (void*)&temp);
}
sleep(1);
return 0;
}
我编译了它:
gcc p_test.c -lpthread
我跑了。它打印了2 2 3 3
。我又跑了它打印了2 3 3 2
。
我的问题是:
为什么2
或3
打印两次?
为什么不打印1 3 2 0
或其他任何结果?
答案 0 :(得分:7)
这里的主要问题是你正在获取局部变量temp
的地址,然后在变量范围之外使用该指针 - 一旦你退出循环的一次迭代,你的指针temp
变为无效,您不得取消引用它。
答案 1 :(得分:3)
您将指向临时变量的指针传递给线程创建函数,并且此临时值在循环块结束时超出范围。在我看来,编译器正在重用临时地址,因此当线程执行时,它们会看到相同的地址位置。
如果你这样做:
int *temp = malloc(sizeof(int));
*temp = i;
pthread_create(&pt[i], NULL, func, (void*)temp);
相反,你应该看到你期望的结果。
在这种情况下,线程函数在打印后需要释放int
以避免内存泄漏。
此外,最好的做法是pthread_join()
您正在等待的主题,而不仅仅是sleep()
。
答案 2 :(得分:0)
因为它打印temp,所有线程共享内存(为什么temp是“共享”由TheJuice解释),所以所有线程“共享”temp。使用mutex或将temp设为私有变量。 Private Variables in Threads
或者您可以像这样使用phtread_join:
int main()
{
pthread_t pt[4];
int i;
for (i =0 ; i < 4; i++)
{
pthread_create(&pt[i], NULL, func, (void*)&i);
pthread_join(pt[i],NULL);
}
//sleep(1);
return 0;
}
答案 3 :(得分:0)
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *func(void* arg)
{
printf("ID=%d\n", (int)arg);
pthread_exit(NULL);
return 0;
}
int main()
{
pthread_t pt[4];
int i;
for (i =0 ; i < 4; i++)
{
pthread_create(&pt[i], NULL, func, (void*)i);
pthread_join(pt[i],NULL);
}
return 0;
}