创建
pthread是一个第三方库,编译时要加链接选项
ps -aL查看线程
理解线程id
如何理解线程栈
- 我们使用的线程库是用户级线程库(Linux中没有线程,就无法提供线程系统接口)
- 使用线程动态库是需要加载到内存中,映射到对应的地址空间中
- 执行线程创建的可执行程序后,程序加载到物理内存,CPU执行到creat函数,会发现需要调线程库,
则直接将动态库也加载到内存,映射到共享区,跳转到共享区再执行对应的函数代码创建线程,结果再返回到代码区 - 所有代码的执行,都是再进程地址空间中执行的
线程的局部存储
代表线程除了保存临时数据可以有自己的线程库,
线程库还提供了一个功能,想定义一个全局变量,每个线程独自私有该变量,就可以使用线程局部存储
__thread修饰变量名,该变量就属于各个线程私有的信息(可以理解成该变量都拷贝了一份给各个线程)
gettid获取线程lwp值,不能直接调用,要使用syscal函数
线程在运行时会产生临时数据
线程要有自己的栈结构
pthread_t pthread_self(void)获取调用者的线程id
线程入口参数传递:
- tn也是临时变量,但是传参时是将其里面保存的内容传递,所以没有出现错误;
- 最后还要把堆上开辟的空间释放,释放应该由线程释放;
- 不能由主线程释放,因为工作线程还要使用;
线程入口函数传参注意:
- 线程入口函数参数不能传递临时变量;
- 传递堆上的空间,在线程不使用时由线程释放;
- 线程入口函数参数不仅可以传递内置类型,也可以传递自定义类型;
如何在一个进程疯狂使用CPU,但里面包含多个线程,如何分析是哪个线程所导致?
- top -H -p +进程号,使用该命令可以查看到其底下所有线程的资源信息
- 再用pstack +进程号找到具体线程的地址
线程终止
- 线程调用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是退出进程,任何一个线程调用,表示整个进程退出