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

 

 

关于僵尸进程:一般情况下进程终止的时候,和它相关的系统资源也并不是主动释放的,而是进入一种通常称为“僵尸”(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设置为分离线程是一种很好的做法。

posted on 2015-06-19 21:25  奶味洋葱头  阅读(900)  评论(0编辑  收藏  举报