我有测试代码:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
pthread_t th_worker, th_worker2;
void * worker2(void *data) {
for(int i = 0; i< 1000000; i++){
printf("thread for worker2----%d\n", i);
usleep(500);
}
}
void * worker(void *data){
pthread_create(&th_worker2, NULL, worker2, data);
for(int i = 0; i< 100; i++){
printf("thread for worker-----%d\n", i);
usleep(500);
}
}
void join(pthread_t _th){
pthread_join(_th, NULL);
}
在main()函数中,如果我调用join(the_worker2):
int main() {
char* str = "hello thread";
pthread_create(&th_worker, NULL, worker, (void*) str);
/* problem in here */
join(th_worker2);
return 1;
}
- &GT;分段错误错误
否则,我打电话:
join(the_worker);
join(th_worker2);
---&GT;行
为什么在上述情况下出现段错误? 谢谢你的帮助!
答案 0 :(得分:1)
如果您发布了所有代码,则您有竞争条件。
main
与worker
的开头同步,但不 worker2
。
也就是说,main
尝试加入th_worker2
worker
之前有机会调用pthread_create
并设置{{1}使用有效 [非null]值。
因此,th_worker2
在第二个th_worker2
完成之前无效,但对于pthread_create
来说已经太晚了。它已经提取main
,其值为NULL,th_worker2
将为段错误。
当您为main
添加联接时,它会起作用,因为保证同步和没有竞争条件。
要在没有连接的情况下实现此保证,请执行以下操作:
th_worker
更好的方法是添加一个额外的变量。有了这个,第一个循环就不需要了[但是我把它留在了]:
int
main()
{
char *str = "hello thread";
pthread_create(&th_worker, NULL, worker, (void *) str);
// give worker enough time to properly start worker2
while (! th_worker2)
usleep(100);
/* problem in here */
join(th_worker2);
return 1;
}