在主函数中调用join子函数pthread
Call join child pthread in main function
我有测试代码:
#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----%dn", 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-----%dn", 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;
}
-->段故障错误
否则,我叫
join(the_worker);
join(th_worker2);
--->OK
为什么在上述情况下会出现分段故障错误?谢谢你的帮助!!!
如果您发布了所有代码,则存在竞争条件。
main
与worker
的开始同步,但不worker2
。
也就是说,在worker
有机会调用pthread_create
并设置具有有效[非null]值的th_worker2
之前,main
正试图加入th_worker2
。
因此,在第二个pthread_create
完成之前,th_worker2
将是无效的,但对于main
来说已经太晚了。它已经获取了具有NULL值的th_worker2
,并且main
将segfault。
当您为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;
}
一个更好的方法是添加一个额外的变量。有了这个,第一个循环就不需要了[但我把它留在了]:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int worker_running;
pthread_t th_worker;
int worker2_running;
pthread_t th_worker2;
void *
worker2(void *data)
{
// tell main we're fully functional
worker2_running = 1;
for (int i = 0; i < 1000000; i++) {
printf("thread for worker2----%dn", i);
usleep(500);
}
return NULL;
}
void *
worker(void *data)
{
// tell main we're fully functional
worker_running = 1;
pthread_create(&th_worker2, NULL, worker2, data);
for (int i = 0; i < 100; i++) {
printf("thread for worker-----%dn", i);
usleep(500);
}
return NULL;
}
void
join(pthread_t _th)
{
pthread_join(_th, NULL);
}
int
main()
{
char *str = "hello thread";
pthread_create(&th_worker, NULL, worker, (void *) str);
// give worker enough time to properly start worker2
// NOTE: this not necessarily needed as loop below is better
while (! th_worker2)
usleep(100);
// give worker2 enough time to completely start
while (! worker2_running)
usleep(100);
/* problem in here (not anymore!) */
join(th_worker2);
return 1;
}
相关文章:
- 从 c 或 cpp 系列子函数返回到主函数
- C++:为什么我的掷骰子函数在掷骰子数量时只返回偶数整数?
- 禁止子函数调用父级的抽象(或虚拟)函数
- 我想要一个具有子函数的函数访问相同的命名函数,而不使用它取决于其子类的类
- 添加字符串类型的类成员会导致调用基类函数而不是子函数
- C++调用子函数
- 如何在C++从父实例调用子函数
- 是否有理由大多数/所有 try-catch 示例只对 throw 语句使用 void 子函数
- CRTP 在父级析构函数中调用子函数
- 在函数和子函数中调用相同的关键部分
- 整数模板参数和子函数调用
- 如何在C++中创建具有子函数的对象
- 使用子函数的继承函数
- 从void子函数检索int值到C++中的函数
- 现有的标准函子/函数,用于检查等于 0
- 通过指针修改子函数中函数的局部变量的内容
- 重载算子函数==
- 如何编写返回类型的函数,该类型是其子函数的返回类型
- c++11 子函数中的随机数生成器
- 在主函数中调用join子函数pthread