创建线程后,倘若不进行处理,会出现线程没有执行完,主线程就退出(意味着整个程序退出)的情况,如下例所示,为了避免这种情况,可以使用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();
}