对于调度,两个系统仍不相同,linux的调度器是一种水平的结构,就是调度task_struct,而windows的调度却是一种层次化调度,在调度线程之前要先参考其所在的进程的优先级。但是linux的进程/线程统一化设计也有自己的优点,如果你为一个机制设计两个实体,那么在策略上你就要考虑两个实体,包括它们的互斥,它们的协作等等任何它们之间的交互,然而你只设计一个实体,那么你就可以少考虑很多事情,更加专注地解决需要解决的逻辑,对于linux来说,用task_struct很容易的就可以实现那种分层的层次化调度,而且不同于windows的整体化的严格的必须的分层调度,在linux中,这种分层调度只是调度器的一个策略而已,这就是分组调度,在2.6.25内核得到了增强。在windows中在调度一个线程运行前,必须参考其进程的优先级,这是它的进程/线程分离设计导致的,而对于linux,你想实现任何方式调度只需要给调度器写一个策略既可,调度器为外界提供了调度类,调度组等容器以及一系列的策略设置接口,你想让调度器怎么调度都行,你想实现windows的方式,那么好办,你把所有的属于一个进程的线程放到一个调度组中,然后让调度器分组调度,调度器的分组调度还可以嵌套,层层向上,比如你可以把进程的所有线程作为一组,称组1,然后一个用户的一个类别的进程的所有组1组成组2,然后按照用户组成组3...这种策略很不错,而且依据调度器提供的接口,你还可以做出更好的调度策略。在调度器看来linux的task_struct可以有多种拓扑结构,如果是一个链表,那么就是水平的调度,也就是task_struct的优先级比较然后调度(比如O(n)或者O(1)或者非组方式的cfs),如果是一棵树和简单图,那个就是分组调度了,根据树的高低可以看出组的深浅,你当然可以实现自己的策略使调度器把所有task_struct看成一个图或者一张表,这只是策略实现问题,在windows的调度器看来,所有的线程就是一个链表,然后指向它们的进程,进程也是一个链表,因此调度器看进程和线程就是一张扁平的图。那么除了调度器,别的内核管理机制会看到进程/线程的什么样的拓扑结构呢?众所周知,linux的fork机制可以像细胞分裂一样创建一个又一个新进程,而windows却不是这样的。fork机制让人觉得进程(当然还有线程)们最终会组织成一棵树,比如用pstree可以看到,但是那只是导出给用户的拓扑结构,在内核中其实进程们是一张网状的图,因为各个同级别进程之间会通过链表联系,比如兄弟进程之间的关系,其实在windows中虽然不是fork机制创建新进程,然后也是一张网状图的进程拓扑结构,因为这样容易定位和管理进程,毕竟操作系统再不把进程当回事,也要有进程管理这一块,windows的进程网和linux的进程网所不同的就是linux的网铺开的广度可能更大些,而windows的可能会是扁平状。
回到前面讨论过的问题,unix/linux的本质是任务代理用户访问资源,然后unix把资源统一成了文件这个概念,最终像套接字,管道都成了文件,于是进程作为任务在内核的数据结构,里面必然要有一个表示文件的结构数组,每一个元素代表进程使用的一个文件,这个结构就是打开文件表,对于windows而言,文件并没有被特殊抽象出来,因为没有必要,在windows中,一切都是对象,而且每个对象属于一个类别,实际上每一类对象都代表了一个现实中的实体,比如进程,线程,信号量,文件...windows的本质就是靠这些对象自身的协作满足用户需求而不是访问资源,可是不知道是历史原因导致操作系统理论已经成型还是这么实现不用自己发明*从而更简单,windows还是将进程/线程作为了执行任务的用户代理实体,进程作为容器,线程作为执行绪,于是在进程这个特殊的对象里面必然需要描述所有被这个用户代理使用的对象,这就是进程的对象句柄表,表中的每一个元素代表一个该进程使用的对象,类比在linux中的统一的文件资源架构,只要获得一个文件的访问权限,那么任何进程都可以访问,反过来到了windows中,文件统统被对象替代,同样的,只要获得了对象的访问权限就可以访问该对象,有什么错吗?没有!因此,对象的安全描述符才那么重要,因此,windows中才实现了基于角色的复杂的访问控制机制,因此,才有了跨进程创建线程等机制,对象间互访而已!
本文转自 dog250 51CTO博客,原文链http://blog.51cto.com/dog250/1274145接: