线程概念线程是程序里的一个执行路线。一切进程至少都有一个执行线程线程在进程内部执行本质是在进程地址空间内运行分页式存储管理虚拟地址和页表的由来西靠一下如果在没有虚拟内存和分页机制的情况下每一个用户程序在物理内存上对应的空间必须是连续的每个程序的代码和数据长度不同按照这样的映射方式物理内存将会被分割成各种离散的块运行一段时间后他们占据的物理内存空间可以被回收我们希望操作系统一共给用户的空间必须是连续的但是物理内存不要连续物理内存按照一个固定的长度的页框进行分割有时叫做物理页每个页框包含一个物理页一个页大小等于页框的大小物理内存管理页框的大小会被划分但是物理页很多操作系统会进行管理持续监控struct page结构是操作系统的每个物理页为了节省内存使用了大量的联合体页表页表中的每一个表项指向一个物理页的开始地址在32位系统种虚拟内存的最大空间是4g虽然最后使用的物理内存是离散的但是与虚拟内存对应的线性地址是连续的页目录结构每一个页框都被一个页表中的一个表项来指向了这个1024个页表也需要被管理起来单级⻚表对连续内存要求⾼于是引⼊了多级⻚表但是多级⻚表也是⼀把双刃剑在减少连续存储要求且减少存储空间的同时降低了查询效率缺页异常设想CPU给MMU的虚拟地址在 TLB 和⻚表都没有找到对应的物理⻚该怎么办呢其实这就是缺⻚异常 Page Fault 它是⼀个由硬件中断触发的可以由软件逻辑纠正的错误。假如⽬标内存⻚在物理内存中没有对应的物理⻚或者存在但⽆对应权限CPU就⽆法获取数据这种情况下CPU就会报告⼀个缺⻚错误。由于CPU没有数据就⽆法进⾏计算CPU罢⼯了⽤⼾进程也就出现了缺⻚中断进程会从⽤⼾态切换到内核态并将缺⻚中断交给内核的Page Fault Handler 处理线程的优点创建新线程的代价比新进程小线程占用资源更少能充分利用多处理器的可并行数量线程的缺点性能损失健壮性降低缺乏访问控制编程难度高线程异常单个线程出现问题野指针问题会导致线程崩溃进程也会崩溃线程用途能提高IO密集型程序的用户体验Linux进程vs线程进程间具有独立性线程共享地址空间也就是共享进程资源进程和线程进程是资源分配的基本单位线程是调度的基本单位Linux线程控制POSIX线程库头文pthread.h链接这些线程函数库时要使用编译器命令的“-lpthread.h”创建线程功能创建⼀个新的线程 原型 int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);参数: thread:返回线程ID attr:设置线程的属性attr为NULL表⽰使⽤默认属性 start_routine:是个函数地址线程启动后要执⾏的函数 arg:传给线程启动函数的参数 返回值成功返回0失败返回错误码线程停止线程函数return 这种方法对主线程不适用从main函数return相当调用exit线程可以调用pthread_exit终止自己线程等待已经退出的线程其空间没有被释放仍然在进程的地址空间内。• 创建新的线程不会复⽤刚才退出线程的地址空间。分离线程默认情况下新创建的线程是joinable的线程退出后需要对进行pthread_join操作否则无法释放资源从而造成系统泄露int pthread_detach(pthread_t thread);线程ID及进程地址空间布局pthread_create函数会产生一个线程ID存放第一个参数指向的地址中该线程ID和前面说的线程ID不是一回事pthread_create函数第⼀个参数指向⼀个虚拟内存单元该内存单元的地址即为新创建线程的线程ID属于NPTL线程库的范畴。线程库的后续操作就是根据该线程ID来操作线程的