posts - 200, comments - 8, trackbacks - 0, articles - 0

关于分离线程(转)

Posted on 2012-12-14 11:01 鑫龙 阅读(203) 评论(0)  编辑 收藏 引用 所属分类: linux编程

线程的分离状态决定一个线程以什么样的方式来终止自己。
线程的默认属性,一般是非分离状态,
这种情况下,原有的线程等待创建的线程结束。
只有当pthread_join()函数返回时,创建的线程才算终止,才能释放自己占用的系统资源。
而分离线程没有被其他的线程所等待,自己运行结束了,线程也就终止了,马上释放系统资源。
程序员应该根据自己的需要,选择适当的分离状态。

 

 

关于分离线程的一种用法(转)

 

讲到分离线程,先得从僵尸进程讲起(抱歉,确实不知道线程是否有僵尸一说)。

关于僵尸进程:一般情况下进程终止的时候,和它相关的系统资源也并不是主动释放的,而是进入一种通常称为“僵尸”(zombie)的状态。它所占有 的资源一直被系统保留,直到它的父进程(如果它直接的父进程先于它去世,那么它将被init进程所收养,这个时候init就是它的父进程)显式地调用 wait系列函数为其“收尸”。为了让父进程尽快知道它去世的消息,它会在它死去的时候通过向父进程发送SIGCHLD信号的方式向其“报丧”。

所以一旦父进程长期运行,而又没有显示wait或者waitpid,同时也没处理SIGCHLD信号,这个时候init进程,就没办法来替子进程来收尸。这个时候,子进程就真的成了”僵尸“了。

同理:

如果一个线程调用了这个函数,那么当这个线程终止的时候,和它相关的系统资源将被自动释放,系统不用也不能用pthread_join()等待其退 出。有的时候分离线程更好些,因为它潜在地减少了一个线程回收的同步点,并且pthread_join()这个API确实也是相当地难用。

为了让主线程省去去子线程收尸的过程,可以使用

int pthread_detach(pthread_t thread);

来让子线程处于分离状态,就不需要父线程再pthread_join了。

我们来看一种分离线程的用法。上次别人问道一种情况,我发现必须要分离子线程:

void* task1(void*);

void usr();

int p1;

int main()
{
p1
=0;
usr();               
//调用这个认为是你的触发函数
    getchar();
return 1;
}

void usr()
{
pthread_t  pid1;
pthread_attr_t attr;
/*这里做你的事情*/
if(p1==0)
{    pthread_attr_init(
&attr);
pthread_attr_setdetachstate(
&attr, PTHREAD_CREATE_DETACHED);       //因为你的线程不便于等待的关系,设置为分离线程吧    
            pthread_create(&pid1, &attr, task1, NULL);

}

}

void* task1(void *arg1)
{
p1
=1;                           //让子线程不会被多次调用
    int i=0;
printf(
"thread1 begin./n");
for(i=0;i<100;i++)
{
sleep(
2);                  
printf(
"At thread1: i is %d/n",i);       
usr();                    
//继续调用
   }
pthread_exit();
}
 

我 们看到,在这里task1这个线程函数居然会多次调用其父线程里的函数,显然usr函数里,我们无法等待task1结束,反而task1会多次调用 usr,一旦我们在usr里pthread_join,则在子线程退出前,有多个usr函数会等待,很浪费资源。所以,此处,将task1设置为分离线程 是一种很好的做法。


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理