linux
(和
unix
)将进程的概念说的很大,而且很细,进程不再仅仅拥有一个执行流,而是有了一个容器,其实某种意义上它本身就是一个容器。
unix
传统将进程想成
了一个执行绪,概念真的就是如此简单,简单的东西往往是好的东西,复杂的反而会更加糟糕。进程概念的简单性使得
fork
可以如此美妙如此简单的实现,使得
创建一个可执行映像可以分为
fork
和
exec
,正如我的前文所述。更加重要的是,传统
unix
将执行绪和执行过程中需要的资源分开了,如此就可以将资源
作为一件物品在进程之间传递,这丝毫没有问题。
linux
继承了
unix
一切好的东西,它的进程由
task_struct
表示,内部有很多表示资源的字段,比如
files_struct
表示打开的文
件,
unix
中的
fork
的意义就是进程复制,复制是如此的简单且直观,使得你只需要复制当前的一切就可以了,复制往往比创造要简单得多,就像我们小的时
候总喜欢抄作业一样,后来又有了写时复制,更加节约了时间增加了效率,于是
fork
的意义就是复制一切资源,而对于执行绪内部的资源比如地址空间采取写时
复制的策略。因此,文件描述符作为打开文件的索引其实也是一种资源,这样的话在
fork
的时候就可以传递给子进程了。
linux
就是这样像叉子一样不断的
fork
最终形成一片天地。
linux
一向以地址空间的隔离作为其安全的根本,但是为何却可以拿资源传来传去呢?地址空间不也是一种资源吗?互相传递资源不会引起不安全吗?当然不会
不安全,
linux
的进程结构设计的非常好,资源的共享完全在可控范围内,也就是说你可以选择传递或者不传递,一切由你决定,如果出了问题就是你自己造成
的而不是操作系统造成的。内核当然知道什么东西是可以安全传递的,比如文件描述符,该描述符对应的文件可以被子进程随意读写,而且文件描述符可以不变,对
于地址空间,它是进程的根本,在
fork
的时候是完全复制的(现在是写时复制),其实地址空间和文件描述符都是资源,那为什么内核对待它们的态度却不同
呢?对于文件描述符的复制是浅拷贝而对于地址空间的拷贝却是深拷贝,
why
?这就涉及到一个资源性质的问题。我们看一下文件和地址空间作为资源有何不同,
其实很容易就可以看出它们的不同,对于文件是共享资源,它并不是进程的内禀属性,进程可拥有可不拥有,因此它当然可以被共享,而对于地址空间,它是进程的
内禀属性,进程的定义中明确规定地址空间不能和别的进程共享,因此它就必须被进程独享,因此在
fork
的时候要深拷贝。举个例子,丈夫这个定义,它表示此
人拥有一个妻子,妻子就是他的一个资源,而且他也可以拥有一支钢笔,但是对于丈夫而言妻子是他的内禀属性,因此妻子是他独有的,但是钢笔和丈夫并没有必然
关系,因此钢笔是可以让别人用的。