您的位置:首页 > 运维架构 > Linux

Linux下如何安全退出线程

2015-07-26 19:04 435 查看

正确退出线程

背景

最近发现以前工作中写的代码有个比较严重的bug,在这里做一下笔记,并做适当扩展,防止以后出现类似的问题。

问题背景是这样的,有一个管理设备用的进程需要从远端FTP服务器上下载软件包,以执行升级操作。管理进程通过select监听socket文件描述符,有消息到来时就调用对应的消息处理函数处理消息。执行从FTP服务器上下载软件包的操作,就是为了响应软件下载消息。在这种框架下,肯定是不能直接在消息处理函数中执行下载任务的,因为这可能导致管理进程阻塞,无法响应其他消息,因此想到重新启动一个线程来执行下载任务。

功能实现非常简单,收到软件下载消息后,在消息处理函数中启动一个线程执行下载任务,线程创建成功后,消息处理函数返回,继续等待下一条消息,并不会等待下载线程结束。由于看Linux系统编程时囫囵吞枣,导致学艺不精,天真地以为下载线程能不留痕迹的安全退出。实际情况却是,默认创建的线程是非分离态的(joinable),这种情况下,父线程需要调用pthread_join来等待子线程结束,只有当pthread_join返回时,子线程才会真正结束,才会释放占用的系统资源。如果想要线程结束后,立即释放占用的系统资源,需要设置线程为分离线程(detached)。

创建分离线程

有两种方法可以设置线程为分离线程,分别是创建时设置线程属性和调用pthread_detach.下面分别来介绍这两种方法。

设置线程属性

创建线程时,可以通过pthread_create的第二个参数传递线程属性。线程有许多属性可以设置,比如堆栈大小、调度方式等,我们这里只设置分离属性,方法如下:

1.初始化一个线程属性对象。

#include <pthread.h>
int pthread_attr_init(pthread_attr *attr);


2.设置分离属性。

#include <pthread.h>
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);


这两个函数一个用于设置状态,一个用于获取。设置状态用的两个标志分别为PTHREAD_CREATE_JOINABLE和PTHREAD_CREATE_DETACHED.后一个用于设置线程为分离线程。设置为分离态后,就不能调用pthread_join来获取线程的退出状态了。

3.创建线程,并把设置好的线程属性对象传递给pthread_create函数。

完整代码如下,代码比较简略,没有进行错误处理,实际写代码最好判断一下调用函数的返回值,以确定函数执行成功:

pthread_t a_thread;
pthread_attr_t thread_attr;

pthread_attr_init(&thread_attr);
pthread_attr_setdetachstate(&pthread_attr, PTHREAD_CREATE_DETACH);
pthread_create(&a_thread, &thread_attr, thread_function, NULL);
pthread_attr_destroy(&pthread_attr);


调用pthread_detach

根据pthread_detach的man手册给出的例子,在子线程启动后,通过如下方式调用:

pthread_detach(pthread_self());


如何创建分离线程的方法,这里就讲完了,希望对各位朋友有用,不会和我一样掉进同一个坑里。多进程编程其实会有类似的问题,也就是僵尸进程的问题,这个主题会在下一篇博客中分析,敬请期待。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: