创建
pthread是一个第三方库,编译时要加链接选项
ps -aL查看线程
理解线程id
打印pthread_creat函数参数tid,这是一个非常大的数,
pthread_t是无符号长整形,是一个地址
究竟是什么地址呢,先做一些准备工作
- 线程是一个独立的执行流
- 线程一定会在自己的运行过程中产生临时数据(比如调用函数,或者定义局部变量)
- 线程一定要有自己独立的栈结构
如何理解线程独立栈
- 我们使用的线程库是用户级线程库(Linux中没有线程,就无法提供线程系统接口)
- 使用线程动态库是需要加载到内存中,映射到对应的地址空间中
- 执行线程创建的可执行程序后,程序加载到物理内存,CPU执行到creat函数,会发现需要调线程库,
则直接将动态库也加载到内存,映射到共享区,跳转到共享区再执行对应的函数代码创建线程,结果再返回到代码区- 所有代码的执行,都是再进程地址空间中执行的
pthread_t究竟是什么
库可以创建多个线程,线程的管理是由库管理的(各种线程函数)
管理方式:先描述,再组织
所以在共享区所对应的库中,就有一个结构体来描述线程的属性
每创建一个线程,会在 库 里创建一个线程控制块(对比进程PCB理解)
这个结构里面就有一个指针,指向用户空间某一个位置,代表曾经申请的栈空间
将线程控制块的地址返回,所以pthreat_t是用户级线程控制结构体的起始地址
主进程的独立栈结构用的是地址空间中的栈区结构
新线程的独立栈结构用的是线程库在物理内存维护的
线程的局部存储
代表线程除了保存临时数据可以有自己的线程库,
线程库还提供了一个功能,想定义一个全局变量,每个线程独自私有该变量,就可以使用线程局部存储
__thread修饰变量名,该变量就属于各个线程私有的信息(可以理解成该变量都拷贝了一份给各个线程)
gettid获取线程lwp值,不能直接调用,要使用syscal函数
线程有独立的PCB,指向主线程的地址空间,这里栈区只有一个,代码区好划分(以函数方式),数据可以被线程共享,堆区可以自己去申请,
但是他是一个线程id,和lwp值不同
以16进制打印就像一个地址(实际就是地址)
线程在运行时会产生临时数据
线程要有自己独立的栈结构
pthread_t pthread_self(void)
获取调用者的线程id
两个线程有各自的栈
线程入口参数传递:
- tn也是临时变量,但是传参时是将其里面保存的内容传递,所以没有出现错误;
- 最后还要把堆上开辟的空间释放,释放应该由线程释放;
- 不能由主线程释放,因为工作线程还要使用;
线程入口函数传参注意:
- 线程入口函数参数不能传递临时变量;
- 传递堆上的空间,在线程不使用时由线程释放;
- 线程入口函数参数不仅可以传递内置类型,也可以传递自定义类型;
如何在一个进程疯狂使用CPU,但里面包含多个线程,如何分析是哪个线程所导致?
- top -H -p +进程号,使用该命令可以查看到其底下所有线程的资源信息
- 再用pstack +进程号找到具体线程的地址
线程终止
- 线程入口函数的return返回,当前线程就退出
- 线程调用pthread_exit函数,谁调用谁退出
- 线程调用pthread_cancel函数,退出thread线程;
填谁的线程标识符,谁就退出;
线程创建的默认属性:
- 用pthread_creat在创建线程时,线程的属性默认是joinable属性;
- 该属性导致线程在退出时依赖别人回收资源;
- 也就说说线程退出了,但是线程的资源未被回收;
- 需要用线程等待解决
线程等待
线程退出必须被join等待,不然会造成类似进程的内存泄露
一个线程异常,整个进程异常
函数的第二个参数是为了线程退出的退出码
使用:线程函数的返回值是指针类型,则返回时可以写成return (void*)10,再通过retval参数获得
主线程为什么没有获取新线程退出时的信号
没有必要,线程异常,进程就异常了,要通过父进程获取退出码分析
线程被取消后retval是-1
线程等待函数
pthread_join没有等到线程退出,就一直在阻塞
线程分离
新建的线程默认是joinable的,表示可被等待状态,线程退出时必须被等待,否则资源无法释放
在join的时候,新线程不退出,主线程就卡住了
等待线程的目的是1.释放线程资源(前提是线程退出)2.获取线程对应的退出码
如果不想获取退出码,也不想管资源释放,想让OS自己释放,此时join就是一种负担,所以设置程分离属性,自动释放自己的资源
线程分离属性:一个线程被设置成分离属性后,则该线程在退出后,不需要其它执行流回收该线程资源,而是由操作系统回收
- 该函数是设置线程属性
- 这种是在创建时线程设置自己的分离属性,还有一种是线程自己设置成分离属性
如何理解exit
exit是退出进程,任何一个线程调用,表示整个进程退出