线程
一 线程的使用
人们需要线称的主要原因是因为某些应用中发生着多种活动,某些活动会随着时间的推移被阻塞,而将程序分解成不同的线称,程序设计模型会变得简单。
一个进程中的线程共享同一个地址空间和所有可用数据。
第二个使用线称而不是使用进程的原因是因为创建线称的更轻量,创建一个进程所花费的时间是创建一个进程所需要时间的10-100倍。并且也很容易撤销
第三个原因是因为性能,如果多个线称都是cpu密集型的话,并不能增强性能,但是如果存在大量的IO的话就会,多线程就会允许这些活动彼此重叠进行,从而会加快程序的执行速度
二 经典的线称模型
理解进程的另一个角度是,用某种方法把资源集中到一起,比如内存,代码,数据,以及其他资源的地址空间。
另一个概念是,进程用有一个可以执行的线称,该在线称中拥有程序计数器,寄存器,栈等等。
进程用于把资源集中到一起,线称是cpu执行的实体。
同一个进程中的线称不像进程那样存在很大的独立性,没有线程共享相同的地址空间,全局变量,每个线称能够访问地址空间中的任意一个地址
任意一个线称都能够创建一个线程,已经对另一个线程进行读写,甚至清除。
和传统的进程一样,每个线程都有三种状态,运行,就绪,阻塞。
每个线程都有自己的堆栈,程序计数器,寄存器和状态。
三实现线程
实现线程一般有两种方式,一种是在内核中另一种是在用户空间中
一 在用户空间中实现线程
这种方式实现线程的话,内核根本不知道该进程中有几个线程,以为该进程只有一个线程
有点:
用户级线程的一个好处是可以在不支持多线程的操作系统中实现多线程,以前很多操作系统都是属于这种范畴。
在用户空间管理线程的时候,进程要有其专用的线称表,用来跟踪进程中的线程,这些表与内核中的进程表很相似。
包括寄存器,程序计数器,堆栈,状态等等
当用户空间中的某一个正在运行的线称做了一些会引起本地阻塞的事情后,进程就会检测该进程中的其他就绪线称,把该线程转化为其他就绪线称的速度可以非常快,可以比内核线程快一个数量级。这是用户线程的一个极大有点。
用户线程还有一个极大的优点就是每个进程可以制定自己的调度算法。
缺点:
用户线程有很多的有点但是也有很明显的缺点,比如说如何实现阻塞调用,比如说一个线程要读取键盘信息,如果说用户没有任何键盘输入就会导致整个进程停止,线程的意义就是让使每个线称能够实现阻塞调用。
与阻塞调用相似的一个问题是页面中断,当一个线称发现它请求的一个页面不在内存中的时候也会停掉整个进程。
用户线程还有一个问题是如果一个线程开始运行,那么该进程中的其他线程就不能运行,除非是该线称自动放弃cpu,在一个进程内部没有时钟中断,所以不能使用轮转调度。
二 在内核中实现多线程
在内核中实现线程会在内核中存在一个线程表,表中记录了所有线程的信息,这样没创建一个线称,或者终止一个线称都是系统调用,这样的系统开销会比较大。
所有能够阻塞的线程的调用都是以一系统调用的方式实现。
系统内核虽然解决了很多问题但是没有解决所有的问题,比如说信号的问题,信号是发给进程的而不是发给线程的,但是一个进程中有很多线程,到底应该发给哪个呢?
浙公网安备 33010602011771号