58 进程和线程(3)
说完进程再说说线程,线程相比于进程其实有更多可说的内容。首先实现线程调用的数据结构是个栈,该栈记录了调用方法的信息这里面也包括了函数调用及返回的地址。线程肯定是属于某个进程,其控制流可以访问这个进程的资源,对于线程而言内存等数据都是共享的。一个进程可以有多个线程的,所以线程之间的通信还是比较方便,因为线程是共享资源的,所以多线程通讯的机制比起IPC机制更为方便。在OS的环境中,我们可以把线程分成用户线程和内核线程。用户线程的理解当放在OS的整体环境中还是比较好理解,你认为它就是OS提供的某个进程机制下的线程就可以了,因为用户线程往往是受到了OS进程下的控制的为用户开放的线程功能。用户级线程的优势就是因为它是为用户级开放的,所以它的切换效率高。相比于用户级的线程,内核级线程就显得更为条条框框和规规矩矩了。由于OS对指令有完全的控制能力,所以内核线程是应用各种算法来处理分配处理器的时间。前一章,我们说到线程有优先级的概念,优先级高的肯定可以先执行,内核线程的好处就是在于它根本就不需要考虑在什么时候把控制权交给其他线程,从不担心自己的处理时间片是否长了导致其它线程无法执行的问题。所以这一部分对于用户是封闭的,内核会很好处理好线程之间与处理器的资源分配问题。还有一点须注意的是,线程是可以从内核模式转向用户模式,用户模式也可以转向内核模式的。但是这种模式的转换是需要开销的,这部分开销也是可以完全接受的。
之前说了进程的调度算法,其实就是轮换,一个进程运行一段时间后歇菜换另一个进程执行。然而线程的调度算法又是怎样了。在之前我们从课本上学过线程调度算法,从一个纯理论的角度还是有一个大概的认识。基本上可以分为三种,一种为时间片轮询调度算法:这个算法很好理解。就是cpu的处理时间被分成许多块,然后采取轮询的方法分配给每个线程,当线程获取到时间片运行后就按照自己的过程方法执行下去,直到时间段完全用完,或者主动放弃执行。OS会在获得时间片控制权后会控制下一个正在等待的线程。这种线程调度的机制是我们理解多线程并发最常见的思维方式,也是最为实用最为公平的调度处理资源的方式。随着硬件越来越强,线程调度和切换的开销也越来越小。另一种算法为优先级调度,原理也比较简单就是赋予每个线程一个优先级的编号,高优先级的总是优先考虑被处理器执行,在处理这个优先级时OS会形成一个优先级的对列表,用来存储满足条件的线程,当一个线程用完了时间片或者主动放弃处理器执行权时,系统会选择优先级高的线程作为下一个要运行的线程。优先级的调度方法实际上只是在轮询的机制上加上了一个优先级编号的。最后一种方法就是先到先服务的算法,这个算法用到了队列的数据结构先进先出的思想。所有的线程组成了一个队列,最先进入队列的线程最先获得处理器的执行,如果执行完则放出队列,如果没有执行完自己又选择暂停则又被放回队列等待执行的。这种算法看似简单,但是对于线程执行任务的时间长短并未作限制。相比之前集中算法,它还是凸显出一些硬伤。windows的调度算法是前面集中方法的组合。可以说它是一个抢占式的,支持多处理器的调度算法。用链表的方式存储每个处理器要处理的线程,不同优先级的线程分别属于不同的链表。当一个线程满足执行条件时,它首先被挂到当前处理器的一个待分配的链表中,然后在适当的时候将其放到某个处理器对应的优先级的链表中。当处理器在选择线程执行时就会根据线程的优先级选择线程。
(未完待续.............)