线程创建后,避免主线程先于子线程结束的四种方式

创建线程后,倘若不进行处理,会出现线程没有执行完,主线程就退出(意味着整个程序退出)的情况,如下例所示,为了避免这种情况,可以使用sleep、pthread_join、主线程中使用pthread_exit()几种方法来处理:

示例:创建线程后,不做任何处理的情况:

————子线程未执行完,主线程已经退出了。。。。

使用如下几种方法,可以避免这种情况。 

1、使用sleep函数

int main()
{
    pthread_t pid;
    pthread_create(&pid,NULL,foo,NULL);
    cout<<"this is parent thread"<<endl;
    sleep(2);//使用sleep函数,使cpu易主,主线程等待子线程完成。
    return 0;
}

void* foo(void*)
{
    for(int i;i<5;i++)
    {
        cout<<"this is child tread"<<i<<endl;
    }
    phread_exit((void*)0);
}

 解释:可以使用sleep函数,使主线程放弃占用CPU,从而保证子线程运行完成,但存在缺点:由于线程默认是joinable,上述程序并没有对线程资源进行清理。

2、在主线程中使用pthread_exit()代替return,使仅主线程退出,而不是整个程序退出。

void* foo(void*)
{
    for(int i=0;i<5;i++)
    {
        cout<<"this is child tread"<<i<<endl;
    }
    pthread_exit((void*)0);
}
int main()
{
    pthread_t pid;
    pthread_create(&pid,NULL,foo,NULL);
  
    pthread_exit(NULL);
    cout <<"end";
    return 0;
}

 

 分析:发现main函数中的cout <<"end"并没有打印输出,因为此时主线程已经退出了。故 cout<<"end"; return 0;两行可以去掉了。

3、使用phtread_join()函数,线程创建者将挂起等待,并再子线程运行结束后回收线程资源。

void* foo(void*)
{
     for(int i=0;i<5;i++)
    {
        cout<<"this is child tread="<<i<<endl;
    }
    pthread_exit((void*)0);
    return (void*)0;
    //或者pthread_exit((void*)0);
}
int main()
{
    pthread_t pid;
    pthread_create(&pid,NULL,foo,NULL);
    pthread_join(pid,NULL);
    cout<<"end";
    return 0;
}

 

 结果分析:可以看到打印出了end,所以子线程执行完,主线程才继续执行,即:使用pthread_join函数,使主线程阻塞,保证了子线程结束后,主线程才继续运行,同时,主线程清理子线程资源。

 我们知道,int pthread_join(pthread_t thread, void **retval); 函数通过参数 retval回收的线程函数的返回值,参考这篇文章

4、使用pthread_detach()函数和sleep()联合使用

void* foo(void*)
{
     for(int i=0;i<5;i++)
    {
        cout<<"this is child tread="<<i<<endl;
    }
    pthread_exit((void*)0);
    return (void*)0;
    //或者pthread_exit((void*)0);
}
int main()
{
    pthread_t pid;
    pthread_create(&pid,NULL,foo,NULL);
    pthread_detach(pid);
    sleep(2);
    cout<<"end";
    return 0;
}

结果分析:使用detach函数与sleep的联合使用,比单纯的使用sleep要好,因为detach函数能够使子线程分离,从而子线程结束后能够自己清理资源。

 ps:在Qt中创建线程,发现仅用了phtread_detach函数,没有用sleep函数,子线程依然能保证执行完整。

这是因为Qt中,return a.exec();  使程序一直处于事件队列循环中,故程序一直没有没有退出。可以运行程序,从输出结果相比较上几种情况,Qt中没有该程序退出的信息。

void* foo(void*)
{
     for(int i=0;i<5;i++)
    {
        cout<<"this is child tread="<<i<<endl;
    }
    pthread_exit((void*)0);
    return (void*)0;
    //或者pthread_exit((void*)0);
}
int main()
{
    QApplication a(argc, argv);
    pthread_t pid;
    pthread_create(&pid,NULL,foo,NULL);
    pthread_detach(pid);
    
    cout<<"end";
   return a.exec();
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值