Linux系统编程之线程(二) 下

线程控制原语

pthread_join 函数

阻塞等待线程退出,获取线程退出状态
其作用,对应进程中的waitpid()函数

int pthread_join(pthread_t thread, void **retval);
返回值:成功:0;失败:错误号
参数:
	thread:线程ID【注意】不是指针
	retval:存储线程结束状态
【对比记忆】
	进程中:main返回值(return xx)、exit参数均为int型值;等待子进程结束时可以用wait函数获取进程结束状态 wait函数的参数为int*
	线程中:线程主函数返回值、pthread_exit的参数为void*;那么等待线程结束的pthread_join函数参数为void**

【练习】参数retval非空用法
调用该函数的线程将挂起等待,直到id为thread的线程终止。thread线程以不同的方式终止,通过pthread_join得到的终止状态是不同的
(1)子线程通过pthread_exit退出
在这里插入图片描述
(2)子线程通过return退出
在这里插入图片描述
(3) 子线程返回一个自定义的结构体
在这里插入图片描述
【总结】
(1)如果子线程通过pthread_exit退出,那么retval所指向的单元里存放的是传给pthread_exit的参数
(2)如果子线程通过return退出,那么retval所指向的单元里存放的是子线程函数的返回值
(3)如果子线程被别的线程调用pthread_cancel异常终止掉,retval所指向的单元里存放的是常数PTHREAD_CANCELED
(4)如果对子线程的终止状态不感兴趣,可以传NULL给retval参数
(5)一个线程创建后,最好用pthread_join回收该线程,避免产生僵尸线程
【练习】回收多个子线程

pthread_detach 函数

实现线程分离

  • 线程分离状态:指定该状态,线程主动与主线程断开关系。线程结束后,其退出状态不由其他线程获取,而直接自己自动释放。网络、多线程服务器常用
  • 进程若有该机制,则不会产生僵尸进程。僵尸进程的产生主要是由于进程死后,大部分资源被释放,一点残留资源仍存于系统中,导致内核认为该进程仍存在
  • 也可以使用pthread_create中的参数二(线程属性)来设置线程分离
    【练习】使用pthread_detach来实现线程分离
    在这里插入图片描述
    【结果分析】当主线程调用函数pthread_detach将子线程分离后,再使用pthread_join函数将子进程回收,就会报这个错(invalid argument)。由此可见,当使用pthread_detach后,便不再使用pthread_join将子线程回收,子线程会自动释放pcb

让我们将pthread_detach函数注释,再运行
在这里插入图片描述
【结果分析】从子线程的退出码为1可以看出pthread_join函数是运行成功的。
【总结】一般情况下,线程终止后,其终止状态一直保留到其他线程调用pthread_join获取它的状态为止,但是线程也可以被置为detach状态,这样线程一旦终止就立刻回收它占用的所有资源,而不保留终止状态(不需要主线程调用pthread_join来回收它)。不能对一个已经处于detach状态的线程调用pthread_join,这样的调用将返回EINVAL错误。也就是说,如果对一个线程调用了pthread_detach就不能再调用pthread_join

pthread_cancel 函数

杀死(取消)线程 其作用:对应进程中的kill()函数

int pthread_cancel(pthread_t thread);  成功:0;失败:错误号
【注意】线程的取消并不是实时的,而有一定的延时,需要等待线程到达某个取消点(检查点)
【取消点】是线程检查是否被取消,并按请求仅从动作的一个位置,通常是一些系统调用(create,open,pause,close,read,write……)凡有阻塞作有的POSIX C函数都会有取消点, (具体包括哪些,可以查看man 7 pthreads
// printf("aaa\n");   //可作取消点    凡有阻塞作有的POSIX C函数都会有取消点, (具体包括哪些,可以查看man 7 pthreads)
// pthread_testcancel();  //可作取消点  //如果屏蔽所有的取消点.主程序就会堵在pthread_join里.
// printf("bbb\n");//可作取消点
// printf("ccc\n");//可作取消点
// sleep(5);//可作取消点
// printf("ddd\n");//可作取消点
// pthread_testcancel();//可作取消点
// system("ls");//可作取消点

在这里插入图片描述

pthread_equal 函数

比较两个线程ID是否相等

int pthread_equal(pthread_t t1, pthread_t t2);
  • 目前没什么用,可以直接用 == 判断
  • 有可能Linux在未来线程ID pthread_t类型被改为结构体实现

控制原语对比

进程线程
创建fork()pthread_create
退出exit(int)pthread_exit(void*)
等待wait(int*)pthread_join(thread, void**) 阻塞等待
杀死killpthread_cancel 取消点(man 7 pthreads)
获取IDgetpidpthread_self()
分离pthread_detach() 自动清理pcb
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值