【Linux】线程控制:线程创建、终止、等待、分离等

发布时间:2023年12月17日

注意: 以下所有的接口都是使用的Linux下的原生线程库,所有g++/gcc编译的时候需要加上参数-lpthread,编译pthread动态库。

1、线程的创建pthread_create

相关接口,创建线程函数,成功返回0,失败返回一个错误码。

#include<pthread.h>
int pthread_create(pthread_t* thread,const pthread_attr_t *attr,
void*(*start routine)(void*),void* arg);
  • pthread_t* thread:内核数据类型,输入型参数,获取线程ID。
  • const pthread_attr_t *attr:用于定制各种不同的线程属性,一般置空NULL,这里不提倡自定义设置,因为没有比操作系统最了解线程的属性。
  • void*(start routine)(void):函数指针,线程创建出来所要执行的函数,新创建的线程从start_rtn函数的地址开始运行,该函数只有一个void*类型的参数arg
  • void* arg:想给所创建的线程传入的参数,即线程执行函数中的参数。如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构体中,然后把这个结构的地址作为arg参数传入

2.获取线程id,pthread_self

不应使用全局变量 pthread_t tid,在子线程中通过pthread_create传出参数来获取线程ID,而应使用pthread_self。线程ID是进程内部,识别标志。(两个进程间,线程ID允许相同)

#include<pthread.h>
pthread_t pthread_self(void)
//在哪个线程内部调用,即返回哪个线程的线程ID

3.线程等待pthread_join

一般而言,线程也是需要被等待的,如果不等待,可能会导致类似于”僵尸进程“的问题!看一下相关接口,如下:
成功返回0,失败返回一个错误码。

#include<pthread.h>
int pthread_join(pthread_t thread,void **retval);
  • pthread_t thread:线程ID,要等待哪个线程
  • void **retval:输出型参数,用来获取新线程退出的时候,函数的返回值,即获取线程的退出状态。

代码异常的情况需不需要线程处理???
我们都知道,代码的运行存在三种情况:1.代码运行完结果对。2.代码运行完结果不对。3.代码异常。对于1和2的情况都会有相应的返回值接收,但是对于第3种情况,线程不需要处理,这是进程需要关心的。
此外,如果线程在运行的过程中出现问题,异常崩溃,会导致整个进程崩溃掉!!!

4.线程终止pthread_exit

#include<pthread.h>
void pthread_exit(void *retval)
  • retval:表示线程退出状态,通常传NULL。

注意:
线程中,禁止使用exit函数,会导致进程内所有线程全部退出。
在不添加sleep控制输出顺序的情况下。pthread_create在循环中,几乎瞬间创建5个线程,但只有第1个线程有机会输出(或者第2个也有,也可能没有,取决于内核调度)如果第3个线程执行了exit,将整个进程退出了,所以全部线程退出了。
??所以,多线程环境中,应尽量少用,或者不使用exit函数,取而代之使用pthread_exit函数,将单个线程退出。任何线程里exit导致进程退出,其他线程未工作结束,主控线程退出时不能return或exit。
??另注意,pthread_exit或者return返回的指针所指向的内存单元必须是全局的或者是用malloc分配的,不能在线程函数的栈上分配,因为当其它线程得到这个返回指针时线程函数已经退出了。

线程调用return、pthread_exit、exit总结:
?? return:返回到调用者那里去。
?? pthread_exit():将调用该函数的线程
?? exit: 将进程退出。

此处借鉴于:[https://blog.csdn.net/qq_44177918/article/details/130442584]

5.取消目标线程pthread_cancel

取消目标线程也是线程终止的一种,下面让我们来看一下取消目标线程的接口。

#include<pthread.h>
int pthread_cancel(pthread_t thread)

6.线程分离pthread_detach

上面讲了,线程是需要等待的,否则会出现像僵尸进程一样的问题,那么如果不想等待呢?线程库提供了一种接口,采用线程分离的方法,分离之后的线程不需要被join,运行完毕之后,会自动释放Z状态下的PCB控制块。线程分离的接口,如下:

#include<pthread.h>
int pthread_detach(pthread_t thread);

注意:一个线程被设置为分离之后,绝对不能进行join了!!!主线程不退出,新线程处理业务处理完毕在退出!

文章来源:https://blog.csdn.net/weixin_51692487/article/details/134952052
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。