Linux下如何安全退出线程

来源:互联网 发布:linux命令date格式化 编辑:程序博客网 时间:2024/05/22 04:48

正确退出线程

背景

最近发现以前工作中写的代码有个比较严重的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());

如何创建分离线程的方法,这里就讲完了,希望对各位朋友有用,不会和我一样掉进同一个坑里。多进程编程其实会有类似的问题,也就是僵尸进程的问题,这个主题会在下一篇博客中分析,敬请期待。

0 0