windows系统与Linux系统的进程调度/切换

转载自论文:来源:《进程的多对多(M:N)线程模型研究》李晋

windows调度系统
基于优先级调度

Windows操作系统的调度模块采用的是基于优先级的可抢占调度,保证了一定的实时性支持。Windows调度代码是在内核中实现的,但是这个调度器并不是一个单独的模块或者例程,而是在调度可能触发的位置设置了一个类似触发器的函数,它被称作Windows的分发器(dispatcher)。当一个线程变为就绪态时,或者有线程离开了运行态,再或者线程的优先级和处理器亲和性等发生了改变,都会触发分发器对线程的重新调度。
Windows的优先级被分为32个级别:16个实时级别(16至31),该级别中的线程一定是最先运行,且优先级数不会发生浮动;15个可变级别(1至15),该级别中线程低于实时级别进程运行,其优先级可以根据需要由系统的负载均衡模块实时浮动,但是最高不可达到16;1个留给零页面线程的系统级别(0)。每个线程都有一个基本优先级,它是其进程优先级类别和相对线程优先级的一个函数,而线程的基本优先级根据进程基本优先级来计算。同时,线程还拥有一个当前优先级别,而调度是根据这个优先级别来进行调度判断的。在特定情况下,系统在很短的时间周期内会在动态范围(1至15)之内增加线程的优先级。在PRCB结构中有就绪线程队列整组DispatcherReadyListHead,其中每个队列都代表一个优先级,所有就绪线程就按照其优先级挂入其某个队列。

Windows调度原则

Windows的线程调度系统并没有Linux调度系统那么的复杂,其本身就遵循以下几个调度规则:
1,严格执行按优先级的调度,只要有高优先级就绪线程的存在,低优先级线程就不能得到运行机会。
2,如果有多个相同优先级的就绪线程存在,则按照各线程在就绪队列中的先后次序调度。
3,受调度运行的线程被赋予一个时间片,只要不被更高优先级的线程剥夺,则一直运行直到时间片耗尽。但耗尽之后应当适当降低其优先级(不会低于其基准优先级),然后按照实际优先级继续挂入相应就绪队列尾部。
4,运行中的线程因为需要待待某个事件发生而自愿暂时放弃运行进行睡眠,这时线程并不处于就绪状态,因则不挂入就绪队列。当等待事件发生时,该线程则挂入对应优先级的就绪队列或者直接变为“剥夺者”线程。
5,如果线程运行过程中有更高优先级线程变为就绪线程,则当前运行线程被剥夺。

最后需要注意的是,Windows的‘剥夺式’调度中线程的调度与切换是分离的。即新调度线程并不会导致直接的线程切换。原因是如果此时是在中断服务处理阶段时,系统是不允许发生线程切换的,因为线程切换会引起堆栈的切换,这样的话中断返回时就会返回到另一个新线程的上下文中去运行。因此实际的线程切换可能会滞后一段时间到中断返回。windows的‘可剥夺’调度机制,从实时性角度上来讲还是有一定的条件限制的。

LINUX进程控制

Linux中的进程状态被存储在task_struct的state域中,用来标记当前进程描述符所表示的进程在操作系统中的存在状态,状态名称及其之间的转换关系如下图
这里写图片描述
这里写图片描述
Linux拥有五种不同的进程状态,每个状态都表示了进程的一个特定的运行阶段,五个状态名称及其描述如下:
1,TASK_RUNNING表示运行状态,表示当前进程是可执行的,即进程正在CPU上执行或者进程在运行队列中等待被调度运行。当进程正处于CPU上运行时,则进入该状态的正在运行阶段,当进程从CPU上切换下来但仍处于适合运行的状态时,则进入该状态的就绪阶段。一个进程无论是在用户空间执行还是内核空间执行,其state域中都是这个值。
2,TASK_INTERRUPTIBLE表示可中断睡眠状态,表示当前进程正在睡眠,由其命名可以看出,该状态可以被打断。所以它是一种可以被唤醒的睡眠状态,进程等待的条件达成,系统内核会用通知的方法把进程唤醒并设置为运行态。
3,TASK_UNINTERRUPTIBLE表示不可中断睡眠状态,表示进程正在睡眠且对信号等不做相应,这种状态一般只使用在进程的创建过程中。在进程的正常运行状态下,进程的睡眠等待都是有目的,因此该状态使用的比较少。
4,TASK_ZOMBIE表示僵尸状态,当前进程已经结束了其运行函数并且停止,但是其进程描述符还被保留在系统中以供其父进程获取。
5,TASK_STOPPED表示停止状态,此时进程处于不工作状态,不能被调度运行。该状态是进程接收到SIGSTOP、SIGTSTP、SIGTTIN、SIGTTOU等信号时进入的状态

Linux与Windows的不同

Linux内核中的进程控制块task_struct,同时也是线程在使用的线程控制块。虽然不同的线程库同时也拥有自己的线程数据结构,但是其本质是对task_struct的一层封装。也正因此,Linux的进程在创建之初就是一个可调度的单位,所以在创建好进程的同时,线程也就创建好了。而Windows系统中的进程控制块和线程控制块是完全不相同的两个结构,其进程控制块更像传统的资源管理结构,而线程控制块则是程序运行结构。在windows进程创建的过程中,还有较为复杂的专门创建第一个线程的单独过程。
Linux进程与进程之间保持很高的独立性,只有通过各种进程间通信的方式才能够相互交流。而Windows系统则不同,一个进程可以为另一个进程的地址空间分配新缓冲区,在里面写入新程序映像,然后为其创建一个新线程并使其执行。同时windows提供了由别的线程挂起另一个进程中线程的运行手段,LInux中并没有这样的接口。
Linux中的fork()操作使得创建出来的子进程自然拥有了父进程的大部分特征,接着在execve()函数中根据权限位图和打开文件表来关闭没有访问权限的打开文件,主要留下stdin、stdout、stderr三个标准输入输出文件。这样创建出的进程里有很多父进程的遗留特征,父子关系非常明显。而windows进程在创建子进程的时候就可以规定是否遗传已打开的各种对象,而且大部分的进程线程管理资源和运行资源都是新建立的,新进程与老进程之间的联系非常小。
Linux中的拥有task_struct的单位都可以被调度,这样的话每个线程都具有被调度的策略和优先级,且按POSIX中的定义来区分的话Linux进程和线程在调度时候甚至是平级调度,一个线程可以与进程拥有同样的调度机会。Windows中首先进程拥有一层调度优先级,然后同进程内的线程又拥有一层调度优先级。这是一种层次结构,进程优先级过低的话其内部线程的优先级不会高。Windows系统中的进程是不会被调度的,因为本身没有运行资源,必须依靠线程来运行。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值