您的位置:首页 > 其它

线程的分离状态

2013-07-17 10:33 176 查看
线程的分离状态决定一个线程以什么样的方式来终止自己。

线程的默认属性,一般是非分离状态,

这种情况下,原有的线程等待创建的线程结束。

只有当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设置为分离线程 是一种很好的做法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: