进程VS线程
目录
一.进程vs线程
二.线程概念
1.5 线程的优点
1.6 线程的缺点
三.页表
3.1 为什么会有页表?
3.2 我们要怎么办?于是有了页表
3.4 缺页异常
四.线程库使用 (线程控制)不细说了,会灵活应用就行
一.进程vs线程
1.1 进程是资源分配的基本单位
1.2 线程是调度的基本单位
二.线程概念
2.1 线程是“—个进程 内部 的 控制序列”
2.2 一切进程至少都有一个执行线程
2.3 线程 在进程内部运行,本质是在 进程地址空间 内运行
1.3 线程 共享 进程数据,但也拥有自己的一部分数据:
比如:线程ID,一组寄存器,栈等
1.4 一个 进程 可以创建(有)多个线程,他们共享同一块地址空间:比如:data数据段 (Initialized Data Segment(已初始化数据段)存放明确初始化的全局变量和静态变量 例如:int global_var = 100; 和
未初始化数据段..) text代码段/文本段(存放程序的可执行代码(机器指令)) 等。
1.5 线程的优点
1. 创建一个新线程的代价要比创建一个新进程小得多
2. 与进程之间的切换相比,线程之间的切换需要操作系统做的工作要少很多
3. 最主要的区别是线程的 切换虚拟内存空间依然是相同的(共用同一块虚拟地址空间) ,但是进程切换是不同的。
4. 另外一个隐藏的损耗是上下文的切换会扰乱处理器的缓存机制。
5. 线程占用的资源要比进程少。
...
1.6 线程的缺点
1. 性能损失:增加了额外的同步和调度开销,而可用的资源不变。
2. 健壮性降低,缺乏访问控制,因为他们共用同一块虚拟地址空间,因共享了不该共享的变量而造成不良影响的可能性是很大的,换句话说线程之间是缺乏保护。
三.页表
3.1 为什么会有页表?
因为程序运行,大小不同的程序,物理内存将会被分割成各种离散的、大小不同的块。有些程序会退出,它们占据的物理内存空间可以被回收,导致这些物理内存都是以很多碎片的形式存在。
所以我们希望 操作系统 提供给用户的空间(虚拟空间) 必须是连续的,但是物理内存最好不要连续。
3.2 我们要怎么办?于是有了页表
将虚拟内存下的逻辑地址空间分为若干页,将物理内存空间分为若干页框,通过页表便能把连续的虚拟内存,映射到若干个不连续的物理内存页(合理利用物理空间)。这样就解决了使用连续的物理内存造成的碎片问题。
3.3 页目录结构,两级页表的地址转换(级页表对连续内存要求高,于是引入了多级页表,但是多级页表也是一把双刃剑,在减少连续存储要求且减少存储空间的同时降低了查询效率。)等。可以自己了解。
3.4 缺页异常
CPU给MMU的虚拟地址,在TLB和页表都没有找到对应的物理页,该怎么办呢?其实这就是
缺页异常PageFault,它是一个 由硬件中断触发 的可以由软件逻辑纠正的错误。
CPU无法获取数据,CPU没有数据就无法进行计算,CPU罢工了用户进程也就出现了缺页中断,进程会从用户态切换到内核态,并将缺页中断交给内核的PageFaultHandler处理。
四.线程库使用 (线程控制)不细说了,会灵活应用就行
#include<pthread.h> 头文件
4.1 创建线程函数
int pthread_create(pthread_t *thread, // 指向线程标识符的指针const pthread_attr_t *attr, // 线程属性,通常为 NULLvoid *(*start_routine)(void *), // 线程启动函数的指针void *arg // 传递给启动函数的参数
);
4.2 线程终止
void pthread_exit(void *value_ptr); //功能:线程终⽌
int pthread_cancel(pthread_t thread); //功能:取消⼀个执⾏中的线程
4.3 线程等待
int pthread_join(pthread_t thread, void **value_ptr);//功能:等待线程结束
4.4 分离线程
int pthread_detach(pthread_t thread);// 分离线程
pthread_detach(pthread_self()); // 分离自己