分离式线程
Posted Andy Niu ----程序,篮球,羽毛球,科普
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分离式线程相关的知识,希望对你有一定的参考价值。
1、技术都是为了解决实际问题的,考虑下面的场景:
主线程创建一个子线程,子线程做一些任务,在主线程上,等待子线程完成任务,然后向下运行。代码如下:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void* FuncA(void* arg)
{
printf("FuncA Time[%d]\n", time(NULL));
sleep(2);
}
int main(int argc,char* argv[])
{
pthread_t threadA;
pthread_create(&threadA, NULL, FuncA, NULL);
pthread_join(threadA,NULL);
printf("main Time[%d]\n", time(NULL));
getchar();
return 0;
}
[[email protected] thread]$ g++ -o main main.cpp -lpthread
[[email protected] thread]$ ./main
FuncA Time[1477297071]
main Time[1477297073]
2、可以看到,主线程阻塞在pthread_join,那么问题来了,如何让主线程不阻塞在pthread_join呢?
3、上面产生的原因是:默认创建的线程A不是分离的,也就是被主线程关联。
因此,解决办法是:创建线程A的时候,把它设置成分离的,不再被别的线程关联。如下:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void* FuncA(void* arg)
{
printf("First FuncA Time[%d]\n", time(NULL));
sleep(2);
printf("Second FuncA Time[%d]\n", time(NULL));
}
int main(int argc,char* argv[])
{
pthread_t threadA;
pthread_attr_t pAttr;
pthread_attr_init(&pAttr);
pthread_attr_setdetachstate(&pAttr,PTHREAD_CREATE_DETACHED);
pthread_create(&threadA, &pAttr, FuncA, NULL);
int ret = pthread_join(threadA,NULL);
printf("pthread_join ret[%d]\n",ret);
printf("main Time[%d]\n", time(NULL));
getchar();
return 0;
}
[[email protected] thread]$ g++ -o main main.cpp -lpthread
[[email protected] thread]$ ./main
pthread_join ret[22]
main Time[1477298407]
First FuncA Time[1477298407]
Second FuncA Time[1477298409]
不再阻塞。
4、注意:设置了分离状态【PTHREAD_CREATE_DETACHED】,pthread_join返回错误。
改成可结合状态【PTHREAD_CREATE_JOINABLE】,pthread_join返回成功,如下:
pthread_attr_setdetachstate(&pAttr,PTHREAD_CREATE_JOINABLE);
[[email protected] thread]$ g++ -o main main.cpp -lpthread
[[email protected] thread]$ ./main
First FuncA Time[1477298637]
Second FuncA Time[1477298639]
pthread_join ret[0]
main Time[1477298639]
5、还有一种办法,就是创建线程A之后,也就是在线程A运行的时候,进行分离操作,如下:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void* FuncA(void* arg)
{
printf("First FuncA Time[%d]\n", time(NULL));
sleep(2);
printf("Second FuncA Time[%d]\n", time(NULL));
}
int main(int argc,char* argv[])
{
pthread_t threadA;
pthread_create(&threadA, NULL, FuncA, NULL);
pthread_detach(threadA);
pthread_join(threadA,NULL);
printf("main Time[%d]\n", time(NULL));
getchar();
return 0;
}
[[email protected] thread]$ g++ -o main main.cpp -lpthread
[[email protected] thread]$ ./main
main Time[1477298924]
First FuncA Time[1477298924]
Second FuncA Time[1477298926]
6、线程是可结合(joinable)或者分离的(detached)。
对于可结合线程A,被主线程回收资源(比如A的线程栈)和杀死,在主线程join线程A之前,线程A的资源是不会被释放的。
对于分离式线程A,在它终止后,系统会自动释放线程A的资源。
7、对于分离式线程A,考虑一种极端的情况,分离式线程执行特别快,在pthread_create返回之前就已经终止了。
这就意味着,pthread_create返回的数据是垃圾数据。
8、怎么解决上面的问题?
在分离式线程A中执行pthread_cond_timewait函数,让当前线程等待一会,确保pthread_create返回的时候,当前线程还没有终止。
还有一种办法,使用PV操作,分离式线程内先执行P操作,卡在这里。在主线程pthread_create之后进行V操作,
从而确保pthread_create之后,分离式线程刚开始执行。
以上是关于分离式线程的主要内容,如果未能解决你的问题,请参考以下文章