这是我的代码。 这很简单。
#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
或其他结果?
这里最主要的问题是你正在获取局部变量temp
的地址,然后在变量范围外使用该指针 – 只要你退出循环的一个迭代,你的temp
指针变得无效,你必须不要解除引用。
您将一个指向临时变量的指针传递给线程创建函数,并且该临时变量在循环块的末尾超出范围。 在我看来,编译器正在重用临时地址,所以当线程正在执行时,他们会看到相同的地址位置。
如果你这样做:
int *temp = malloc(sizeof(int)); *temp = i; pthread_create(&pt[i], NULL, func, (void*)temp);
相反,你应该看到你期望的结果。
在这种情况下,线程函数需要在打印之后释放int
,以避免内存泄漏。
此外,最好练习pthread_join()
等待的线程,而不是sleep()
。
因为它打印temp,所有的线程共享内存(为什么temp是“共享”由TheJuice解释),所以所有的线程“共享”温度。 使用互斥锁或使temp成为一个私有变量。 线程中的私有变量
或者你可以像这样使用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; }
#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;
}