论坛首页 编程语言技术论坛

[回溯本源] Unix Fork和Windows CreateProcess可以比较吗?

浏览 12121 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-05-11   最后修改:2010-06-18
进程是现代操作系统的一个最基本的概念。书本上说:进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。它可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体。它不只是程序的代码,还包括当前的活动,通过程序计数器的值和处理寄存器的内容来表示。

详细点说:进程的概念主要有两点:

第一,进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。

第二,进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体,我们称其为进程。

在Unix系统中,我们通常用fork来创建一个进程,相应的,在Windows操作系统里,我们用的是CreateProcess,一些对两个平台不熟悉的程序员,常常误以为二者是等同的,并得出了诸如在Windows创建进程比在Unix慢许多等错误结论。

fork时发生了什么?
当fork()系统调用发生时,子进程会拷贝其父进程的所有页面,并将其加载入操作系统为它分配的一片独立内存中。这些拷贝的动作很消耗时间,而且在某些情况下并不需要这么做。如果子进程马上执行了"exec"系统调用(用来执行任何可执行文件)或者Fork()之后就退出进程,拷贝父进程的页面就很不划算,因为exec后包括代码段,数据段和堆栈等都已经被新的内容取代,只留下进程ID等一些表面上的信息仍保持原样,而如果fork完之后我们马上就调用exec,这些辛辛苦苦拷贝来的东西又会被立刻抹掉。

在这种情况下,一种叫copy-on-write (随拷随写)(COW)的技术被采用了,当fork发生时,父进程的页面并没有被拷贝到子进程中,相反,这些页面被父进程和子进程所共享。无论父子进程中谁要去修改页面,系统就为该进程拷贝一个独立的特定页面,然后再对其进行修改。该进程以后就只使用这个新拷贝的页面而不再是共享的那个,而别的进程则继续使用共享的页面。这项技术就叫随拷随写,因为当有进程要写页面的时候,就需要先拷贝页面。

采用了COW技术,Fork时,子进程只需要拷贝父进程的页面表就可以了。产生这种设计是因为有时兼容POSIX的操作系统在Fork之后,并不需要执行Exec,比如apache Web Server就因此而受益,这时候的fork让你想起点什么?恩,有点接近Windows的CreateThread。

socket_accept()
fork()
if (child)
    handleRequest()
else
    goOnBeeingParent()


COW技术使得创建子进程的代价小了许多,但是现实情况下,很多时候Fork会紧跟着一个EXEC,因为Exec必须装载所有的映像,unix还是得花很大的代价来创建一个进程。

阐述到这里,比较公平的比较是 Fork近似于NtCreateThread 而CreateProcess 近似于 fork + execve.

这里为什么说比较公平而已,因为还有别的因素我们还未涉及。

相对于Unix,Windows的设计更有弹性,它是一个多层次的而且更加组件化的操作系统,Windows拥有许多子系统,我们通常说的Windows,只是它的子系统之一,称为WoW(Windows On Windows),其他子系统还包括Wow64,Posix和OS2。 Windows NT内核也支持COW fork,但是只为SFU(Microsoft's UNIX environment for Windows)所使用,SFU进程和Win32进程是不同的东西。

回到Win32的进程创建上来,你会发现Windows为Win32进程创建的过程添加了许多枝节。首先,它需要通知CSRSS进程被创建,CSRSS又调用了LPC,而它要求至少kernel32(NTDll.dll)等动态库要被加载,然后它又要处理许多预保留的工作项目,之后该进程才能被认为是一个Win32进程,之后还有许多枝节要去处理比如解析manifests,程序兼容性检查,程序的限制策略等等等等,这些附加在原始进程创建过程之后枝节,无疑拖累了进程创建速度。

这些巴拉巴拉的事情,让我想起了struts,一个又一个filter被插入一次http request之后。

MS提供了一个组策略可以禁用兼容性检查,这样可以大大提高进程的创建速度。此外Win32的运行库(kernel32.dll等等)还带来了大量注册表读操作和初始化。这些东西对 UNIX, SFU或者原生进程都是不存在的。

不带任何子系统的原生进程的创建速度是很快的,而创建SFU进程要比Win32进程简单得多,也快得多,尽管Win32花了许多力气在加载这些枝节之上,但是一方面,它提高了对客户的友好,另一方面,运行库的预加载使得图形界面的处理速度更快,或者Win32进程天生就是为图形处理做准备的。

运行在Windows里Unix Subsystem之上的XClock.



SFU不是unix仿真系统:


  • 大小: 61.7 KB
  • 大小: 21.8 KB
   发表时间:2010-05-12  
现在我就算在win32下作server的开发,也是优先考虑使用 multi-process。提高健壮性和负载能力。
0 请登录后投票
   发表时间:2010-06-18  
1、WOW提供的是16位Windows的兼容层,可以把它看成是一个16位的模拟器,类似于NTVDM模拟16位DOS一样

2、很多所谓的“子系统”,例如Posix,其实只是一个或几个DLL,按照Posix的标准把底层的API包装了一下而已,甚至大名鼎鼎的OpenGL也是对DirectX的简单包装

3、Windows的设计其实是很拙劣的,文中最后所讲的“Windows的设计更有弹性,它是一个多层次的而且更加组件化的操作系统”等等其实正是Windows的缺点,没办法,商业化带来的后果就是设计思想的匮乏和越积越多的历史包袱
0 请登录后投票
   发表时间:2010-06-18   最后修改:2010-06-18
mallon 写道
1、WOW提供的是16位Windows的兼容层,可以把它看成是一个16位的模拟器,类似于NTVDM模拟16位DOS一样

2、很多所谓的“子系统”,例如Posix,其实只是一个或几个DLL,按照Posix的标准把底层的API包装了一下而已,甚至大名鼎鼎的OpenGL也是对DirectX的简单包装

3、Windows的设计其实是很拙劣的,文中最后所讲的“Windows的设计更有弹性,它是一个多层次的而且更加组件化的操作系统”等等其实正是Windows的缺点,没办法,商业化带来的后果就是设计思想的匮乏和越积越多的历史包袱


1...WOW是16位兼容层。。。汗,那WOW64呢?

2...我说了半天,您一个字儿都不看?Wrap API那是CygWin做的事情,那是不折不扣在Win32 API上模拟POSIX。举个简单的东西, 你在Win32里模拟出COW给我看看?

3...您一句话就把业界公认的更先进的微内核设计打回老家去了?Windows是混合内核,但比起linux的单一内核,它更像微内核
0 请登录后投票
   发表时间:2010-06-18  
1、opengl似乎不是directx的简单包装。
2、个人认为windows内核设计比linux内核设计要先进。不知道为什么多层次更加组件化其实正是缺点。
0 请登录后投票
   发表时间:2010-06-19  
WOW是WOW(专指16位环境),WOW64是WOW64,呵呵不玩文字游戏,我说那些子系统和OpenGL是API Wrap是有根据的,看图






很显然opengl32.dll调用的是ddraw.dll(至于第三方的OpenGL实现,例如SGI的,那就不得而知了),而psxdll.dll最终依赖的是ntdll.dll,众所周知ntdll.dll是用户态的最底层,但是并不是内核态的,微软不是傻子,能够依赖现有实现的,怎么会重来一次呢?

所谓微内核巨内核纯粹炒的是概念,微内核好在哪里?结构清晰合理?那结构清晰合理又得到了什么好处?Who cares?大多数时候关心的是整体架构设计,单单一个内核决定不了什么。

Windows确实层次多,但从来没有实现过真正的组件化,组件之间的依赖性是非常大的,上午还有事就不深入讲了吧,反正真正深入研究过Windows底层的都知道的。

我从一开始写程序就接触的Windows,持续了很多年,也曾为搞懂一个诸如API Hook、Native API之类的问题而沾沾自喜,当时想的是Windows确实“博大精深”啊!但是现在已经厌倦了这一切。俗话讲由简入繁易,由繁入简难,“博大精深”并不能说明所谓的“先进”,“大道至简”才是最高境界
  • 大小: 12 KB
  • 大小: 8.3 KB
0 请登录后投票
   发表时间:2010-06-19   最后修改:2010-06-19
mallon 写道
WOW是WOW(专指16位环境),WOW64是WOW64,呵呵不玩文字游戏,我说那些子系统和OpenGL是API Wrap是有根据的,看图

很显然opengl32.dll调用的是ddraw.dll(至于第三方的OpenGL实现,例如SGI的,那就不得而知了),而psxdll.dll最终依赖的是ntdll.dll,众所周知ntdll.dll是用户态的最底层,但是并不是内核态的,微软不是傻子,能够依赖现有实现的,怎么会重来一次呢?

所谓微内核巨内核纯粹炒的是概念,微内核好在哪里?结构清晰合理?那结构清晰合理又得到了什么好处?Who cares?大多数时候关心的是整体架构设计,单单一个内核决定不了什么。

Windows确实层次多,但从来没有实现过真正的组件化,组件之间的依赖性是非常大的,上午还有事就不深入讲了吧,反正真正深入研究过Windows底层的都知道的。




第一、WOW很显然是你在玩文字游戏了。莫非我的写上WOW16,WOW64好骗取稿费?

第二、子系统和API有截然的不同,不要顾左右而言它。至于结构图,我已经贴在上面。我想你根本没玩过子系统。胡乱猜测而已。你也可以去dump一下posix.exe,依赖的win32 api只有寥寥几个而已。

第三、你扯OpenGL32.dll wrap了ddraw.dll里,那么请问用了的哪些个API呢?还是让我们看看你砍到的那些图的余下部分,有图有真相



OpenGL32.dll提供了多少个API: 368个,1:368,果然是一叶障目啊,你还真奸猾,真能扯淡

至于ntdll.dll,那是WOW进入内核态的总入口,OpenGL不是子系统,只是WOW的一部分,不调用ntdll.dll才见鬼了。
  • 大小: 91 KB
0 请登录后投票
   发表时间:2010-06-19  
晕了,我贴一段opengl的吧,也是从网上copy的。
OpenGL硬件加速

  在Windows平台上,OpenGL驱动可能有三种模式:纯软件、MCD和ICD:

    *

      纯软件模式:微软提供一个OpenGL的软件实现,所有渲染操作均由CPU完成,速度很慢。如果安装系统时使用Windows自带的显卡驱动程序,那么 OpenGL程序就会运行在软件模式下。而且由于微软有自己的Direct3D,所以对OpenGL的支持很消极,它的OpenGL纯软件实现只支持 OpenGL1.1,而目前OpenGL的最新版本为1.4
    *

      MCD(Mini Client Driver):MCD是早期微软在Windows NT上支持OpenGL时,为了简化驱动开发时使用的一个模型。在这个模型中,OpenGL渲染管线的变换、光照部分仍然由软件实现,而光栅化部分则由硬件厂商实现,因此只要硬件支持,MCD可以硬件加速光栅化部分。MCD虽然可以简化驱动开发,但是功能限制太大,现在市面上的3D加速卡均支持硬件变换和光照,MCD却不能利用这一特性,看上去MCD已经没有存在的价值
    *

      ICD(Installable Client Driver):ICD是一个完整的OpenGL驱动模型,比MCD复杂得多。硬件厂商要实现完整的OpenGL渲染管线,如变换、光照、光栅化等,因此只要硬件支持,ICD可以硬件加速整个OpenGL渲染管线。我们通常说的OpenGL硬件加速就是指的通过ICD模型获得的硬件加速,而现在硬件厂商提供的OpenGL驱动程序也都是依照ICD模型开发的。主要硬件厂商的ICD已经可以支持OpenGL的最新版1.4

 

  Windows怎么实现OpenGL硬件加速呢?OpenGL32.dll是微软的OpenGL 1.1纯软件实现,我们的程序都要动态链接到这个 dll。如果安装3D芯片厂商的驱动程序,会将一个不同名字的dll放到Windows系统目录下,比如在Windows 2000下安装 nVIDIA GeForce2 MX的驱动程序,会在系统目录下放一个nvoglnt.dll(这就是nVIDIA的OpenGL驱动),并在注册表中登记nvoglnt.dll,让Windows知道硬件加速OpenGL驱动的名字,以后运行OpenGL程序,OpenGL32.dll就会把 OpenGL调用直接转到nvoglnt.dll。

 

    Windows平台上,一个OpenGL程序是否使用硬件加速由三个因素决定,这三个因素缺一不可,否则程序都会运行于纯软件模式:

    *

      是否有一块3D加速卡
    *

      是否安装了显卡厂商提供的最新的驱动程序,Windows自带的显卡驱动程序并不会提供 OpenGL硬件加速能力
    *

      指定的像素格式是否被显卡硬件所支持
0 请登录后投票
   发表时间:2010-06-19  
不要很显然的就:opengl是directx的封装了。
0 请登录后投票
   发表时间:2010-06-19  
单单从导入库来猜测有时候并不一定正确。

我虽然不能说对windows内核很熟悉,但windows的组件即使依赖性很强,也比linux要好些。
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics