一、线程的概念
课本:线程是比进程更加轻量化的一种执行流/线程是在进程内部执行的一种执行流
我们:线程是CPU调度的基本单位/进程是承担系统资源的基本实体
地址空间是进程的"资源"窗口,我们通过栈去访问我们的变量,堆去访问用户空间,PCB的创建要从零开始,他要管理文件, 地址空间,加载页表,初始化字段,代码数据,有了进程后,创建线程时,只需要参加资源的分配
现在的进程:
内核有多个执行流的进程
在Linux下我们可以称线程为轻量级进程
线程是比进程更加轻量化的一种执行流?
线程创建更简单
线程切换比进程切换效率更高
1.切换的寄存器少
2.CPU中有硬件cache,会预加载目前访问的附近的代码,称他们为热数据,线程间切换不需要切换cache,切换进程cache立即就失效,所以切换进程就得切换cache。
线程是在进程内部执行的一种执行流?
线程在进程的地址空间中运行
Linux下进程的实现方案
多个PCB指向同一份资源
二、线程的理解
线程的优缺点:
优点:创建释放代价小
缺点:缺乏访问控制
健壮性降低 例如除0错误,进程收到信号,由于信号处理方法共享,所有线程也全退出了
线程共享:当前进程的文件描述符表,每种信号的处理方式,当前工作目录,用户id和组id
线程私有:线程id,独立的栈结构,一组寄存器(执行流的上下文)
三、线程控制 *
创建线程
创建的线程去执行了自己的函数。
定义一个全局变量,子线程改变,主线程会改变吗?
会改变,由此可见,与子进程不同,线程是与主线程共享资源的.
CPU是以PID调度还是LWP? LWP
代码 ps -aL 查看线程
他们的PID相同,但是LWP不一样。
时间片也会被线程瓜分,时间片也是资源
编译时需要链接 -lpthread
**给线程传参?**可以传递对象
产看线程自身id
pthread_self
pthread_self获取自身id,打印当前线程id
将pthreadid打印成16进制ToHex
thread id本质上是一个地址
线程终止
return nullptr 线程终止
exit(13)? 进程终止
pthread_exit(nullptr)
pthread_cancel 终止线程
- pthread_exit 用于正常结束当前线程。
- pthread_cancel 用于请求取消另一个线程。被取消的线程返回-1 PTHREAD_CANCELED
如果线程异常退出了?需要获取吗?
整个进程也出现异常,只需要获得进程的信号。
线程等待问题
阻塞式等待,系统控制主线程最后一个退出
线程默认被等待
线程退出,没有等待,类似于进程的僵尸问题
线程退出时,主线程如何获取新线程的返回值 pthread_join(tid,nullptr) 阻塞式等待
retval为输出型参数
如果主线程不愿意去阻塞等待另一个线程? 分离模式
分离模式(建议主线程最后一个退出)
默认情况下,新创建的线程是joinable的,线程退出后,需要对其进行pthread_join操作,否则无法释放 资源,从而造成系统泄漏。 如果不关心线程的返回值,join是一种负担,这个时候,我们可以告诉系统,当线程退出时,自动释放线 程资源。
pthread_detach(pthread_self())
分离模式下的线程也可以被取消cancel
主线程需要去得到线程的返回值
使用joinable默认等待
用户级线程
上述接口都不是系统直接提供的接口,而是原生现场库pthread的接口
线程的视线是在用户层的,所以Linux称线程为用户级线程
由于要让用户看到线程的概念,所以在pthread库内对线程进行管理