线程的概念
一、重谈地址空间
每一行代码都有地址,函数连续的代码地址构成的代码块,一个函数对应一批连续虚拟地址。
二、线程
1、理解线程
在进程内部运行,CPU调度的基本单位。
windows有真正意义上的进程(pcb)和线程(tcb),有独立的数据结构和调度算法。
但是Linux线程设计复用进程代码。
所以在CPU中 task_struct <= 进程,CPU不区分进程还是线程,因为两个执行方法是一样的,CPU看到的执行流 <= 进程,叫轻量级进程。
2、创建线程
pthread_t* thread:线程id
const pthread_attr_t* attr:线程属性
void* (*start toutine)(void*):函数指针,新进程的执行方法
举例
三、线程的优势和劣势
1、优势
创建一个新线程的代价要比创建一个新进程小得多
与进程之间的切换相比,线程之间的切换需要操作系统做的工作要少很多
线程占用的资源要比进程少很多
能充分利用多处理器的可并行数量
在等待慢速I/O操作结束的同时,程序可执行其他的计算任务
计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现
I/O密集型应用,为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作。
问题:为什么线程调度成本比进程低?
进程A被调度时会把内存中相关数据调入CPU的cache,叫热数据,若切换进程B,cache中的热数据全部作废,重新加载进程B的数据,导致速度变慢。
2、劣势
性能损失:个很少被外部事件阻塞的计算密集型线程往往无法与共它线程共享同一个处理器。如果计算密集型 线程的数量比可用的处理器多,那么可能会有较大的性能损失,这里的性能损失指的是增加了额外的 同步和调度开销,而可用的资源不变。
健壮性降低:编写多线程需要更全面更深入的考虑,在一个多线程程序里,因时间分配上的细微偏差或者因共享了,不该共享的变量而造成不良影响的可能性是很大的,换句话说线程之间是缺乏保护的。最典型的就是如果一个进程中的一个线程出错就会导致整个进程崩溃。
缺乏访问控制:进程是访问控制的基本粒度,在一个线程中调用某些OS函数会对整个进程造成影响。
编程难度提高:编写与调试一个多线程程序比单线程程序困难得多。
3、线程的私有属性
线程其实大部分属性和进程属性相同,但是每一个线程一定会有属于自己的属性。
线程ID,一组寄存器,栈,errno,信号屏蔽字,调度优先级...
其中最重要的两个是寄存器和栈。
寄存器
进程在调度时不会一下子执行完再执行下一个,CPU的调度要遵守公平性,所以没执行完的进程会有属于自己的寄存器去保留上下文数据,供下一次调度时的数据恢复。
线程也是如此,他也会有自己的寄存器。
栈
线程运行时会形成各种临时变量,必须保存在自己的栈上。