线程篇--线程常⽤操作(线程号)
进程号⽤ pid_t 数据类型表⽰,是⼀个⾮负整数。线程号则⽤ pthread_t 数据类型来表⽰,Linux 使⽤⽆符号长整
数表⽰。
1、pthread_self函数
#include <pthread.h> /** * 获取线程号. * @return 返回调⽤线程的线程. */ pthread_t pthread_self(void);
2、pthread_equal函数
/** * 判断线程号 t1 和 t2 是否相等。为了⽅便移植,尽量使⽤函数来⽐较线程 ID. * @param t1 待判断的线程号. * @param t2 待判断的线程号. * @return 相等: ⾮0; 不相等: 0. */ int pthread_equal(pthread_t t1, pthread_t t2);
3、pthread_create函数
#include <pthread.h> /** * 创建⼀个线程. * @param thread 线程标识符地址. * @param attr 线程属性结构体地址,通常设置为 NULL. * @param start_routine 线程函数的⼊⼝地址. * @param arg 传给线程函数的参数. * @return 成功: 0; 失败: ⾮0. */ int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg ); // 由于pthread_create的错误码不保存在errno中, // 因此不能直接⽤perror()打印错误信息, // 可以先⽤strerror()把错误码转换成错误信息再打印。
4、线程资源回收
pthread_join函数,会阻塞。
#include <pthread.h> /** * 等待线程结束(此函数会阻塞),并回收线程资源,类似进程的 wait() 函数。如果线程已经结束,那么该函数 会⽴即返回. * @param thread 被等待的线程号. * @param retval ⽤来存储线程退出状态的指针的地址. * @return 成功: 0; 失败: ⾮0. */ int pthread_join(pthread_t thread, void **retval);
调⽤该函数的线程将挂起等待,直到id为thread的线程终⽌。
thread线程以不同的⽅法终⽌,通过pthread_join得到的终⽌状态是不同的。
总结:
1. 如果thread线程通过return返回,retval所指向的单元⾥存放的是thread线程函数的返回值。
2. 如果thread线程被别的线程调⽤pthread_cancel异常终⽌掉,retval所指向的单元⾥存放的是常数
PTHREAD_CANCELED。
3. 如果thread线程是⾃⼰调⽤pthread_exit终⽌的,retval所指向的单元存放的是传给pthread_exit的参数。
5、线程分离
pthread_detach函数,不会阻塞。
#include <pthread.h> /** * 使调⽤线程与当前进程分离,分离后不代表此线程不依赖与当前进程, * 线程分离的⽬的是将线程资源的回收⼯作交由系统⾃动来完成, * 也就是说当被分离的线程结束之后,系统会⾃动回收它的资源。所以,此函数不会阻塞. * * @param thread 线程号. * @return 成功: 0; 失败: ⾮0. */ int pthread_detach(pthread_t thread);
总结:
1. 线程终⽌后,其终⽌状态⼀直保留到其它线程调⽤pthread_join获取它的状态为⽌。但是线程也可以被置为
detach状态,这样的线程⼀旦终⽌就⽴刻回收它占⽤的所有资源,⽽不保留终⽌状态。
2. 不能对⼀个已经处于detach状态的线程调⽤pthread_join,这样的调⽤将返回EINVAL错误。也就是说,如果已
经对⼀个线程调⽤了pthread_detach就不能再调⽤pthread_join了
6、线程退出
pthread_exit函数,资源不会被释放。
#include <pthread.h> /** * 退出调⽤线程。⼀个进程中的多个线程是共享该进程的数据段,因此,通常线程退出后所占⽤的资源并不会释放. * @param retval 存储线程退出状态的指针. */ void pthread_exit(void *retval);
总结:
1. 线程从执⾏函数中返回。
2. 线程调⽤pthread_exit退出线程。
3. 线程可以被同⼀进程中的其它线程取消。
7、线程取消
pthread_cancel函数
#include <pthread.h> /** * 杀死(取消)线程. * @param thread ⽬标线程ID. * @return 成功: 0; 失败: 出错编号. * 注意: 线程的取消并不是实时的,⽽⼜⼀定的延时。需要等待线程到达某个取消点(检查点) */ int pthread_cancel(pthread_t thread);
pthread_testcancel(); //设置取消点.