exec的不同实现--鸠占鹊巢还是功成身退

简介:
exec函数可以执行一个进程,是Run-Time Library里面的特性,标准上并没有给出什么硬性规定,因此各个操作系统平台上就可以有五花八门的实现了,本文介绍linux上的实现鸠占鹊巢和windows下的实现功成身退。 
在linux上,著名的exec函数族可谓是无人不晓,它最著名的特性就是可以实现替换当前进程的地址空间,因此你如果在一个进程当中执行了exec,那 就不要指望exec返回执行exec调用点后面的操作了。exec并不负责创建进程,他只负责替换地址空间,负责创建进程的是由另一个系统调用来承担,就 是fork,所以在linux中典型的创建新的执行映像的方式就是fork+exec,当然在你不想要当前进程的情况下也可以直接exec。而在 windows下,exec却是简单的CreateProcess+ExitProcess的封装,在windows下一切最终都要落实到 win32API的,因此Win32API相当于多出来的一个层次,而不像linux直接进行系统调用完事,从这二者的实现我们可以看出什么端倪吗? 
凡是用过unix的都知道unix的哲学,每次只做并且做好一件事情这个终极哲学,你看fork,连参数都没有,就是创建进程,再看exec,根本不管进 程的事,就是替换地址空间,只有这样,把如何组合的策略交给用户,用户才可以获得最大的自由,从而开发出丰富的应用程序。linux本身是一点策略都不提 供的,它不会帮你做你认为会省力的工作,也就是说,只要是你可以完成的工作它就绝对不插手,比如在不影响当前进程的情况下启动另一个进程,linux认为 没有必要直接提供这样一个系统调用,这里的用户指的是所有系统调用层上面的用户,包括库的设计者。库的设计者或者程序员用户可以随意组合这些现有的系统调 用接口,封装成更加方便的接口,只可惜操作系统并不会帮你,举个例子,fork+exec就有一个封装函数,叫做system。我们反过来看看 windows的策略,windows为了开发者可以最快的进行开发,另外加上它的内核和用户空间是比较同步的进行开发的,联系非常紧密,两个空间非常的 了解对方,因此windows往往会直接提供一些策略,这就增加了操作系统和开发者之间的耦合度,不像在linux下开发,系统调用接口很稳定,一般不怎 么变化,内核空间和用户空间只需要通过这个稳定的接口层通信就可以了,而且彼此完全可以不了解对方,正如我前一篇文章所说,这种特性带来的就是术业有专攻 
的 庞大社区的支持,力量非常强大。既然windows提供了一些用户策略,那么它就明显不适合unix哲学同样是创建进程windows的 CreateProcess函数几乎为用户做完了全部的事情,包括创建进程,映射程序映像,这就是和linux的最大不同了。当然并不能说windows 不好,它也有自己的哲学,作为一个产品,它的开发者深知自己的产品,另外不管是内核还是用户空间策略都是产品的一部分,因此就没有必要区分那么清了,它的 开发者通过会议的方式进行协作,因此他们之间的通信就不一定要局限在系统调用接口了。 
可能有些人会认为windows的exec的方式更加干净,确实有那么一点意思,linux的方式有些罗嗦也有那么一点意思,可是用户真的需要这种所谓的 干净吗?那要看用户是什么样的人了,信奉不同哲学的人往往会因为一点小的分歧大开杀戒。事实上linux的exec和windows的exec根本就不是 一个层面上的,在linux中,exec只是“创建进程”这件事情的“一部分”,而在windows下,exec却包含了“创建进程”这件事情,但是还不 止这件事情,另外还包括“退出当前进程”这件事情,用一句俗语区分它们就是,在linux中,exec的作用是“鸠占鹊巢”,在windows 中,exec的作用一个是“功成”另一个是“身退”。这里就可以看出linux和windows的设计粒度,显然linux更加细化一些,细化的东西组合 起来往往会出现规模效应,功能会很强大,而粗化的东西在扩展的时候功能会受到限制,比如linux可以很简单的实现“功成”+“身退”,就是 fork+exec+exit,其实就是三个只做一件事的系统调用之组合,反过来要在windows下实现“鸠占鹊巢”就不容易了,因此windows中 最细的东西都要比这个“鸠占鹊巢”要粗,于是就受到了限制。这样的话,在linux中就可以在保持pid不变的情况下重新启动自身,而在windows下 这个需求就很难了。 

虽然同样都是exec函数,在linux和windows中的地位却大不相同,当然其位置也不同,在linux中可以很安心的将之放到系统调用门口,因为 它就做一件事,不会有任何副作用,但是在windows下,它的存在纯粹是为了兼容标准C,于是就要用Win32API来封装exec函数,而 Win32API中却没有替换地址空间这么细粒度的操作,于是乎只好仅仅实现语义,于是最终就有了CreateProcess+ExitProcess的 组合,有人可能会问这不也是一个组合吗?是的,这是一个组合,但是这是由只做一件事的函数作为元素组合的吗?显然不是。



 本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1274301

相关文章
|
1天前
|
Unix Docker 容器
使用docker 启动naocs 报错出现:standard_init_linux.go:241: exec user process caused "exec format error"
```markdown Error in Docker container startup: "standard_init_linux.go:241: exec user process caused \"exec format error\"". Occurred at 2024-06-29 09:26:19.910, followed by a failed hook with a syslog delivery error at 09:27:20.193. Seeking solutions from experts. ```
|
11月前
|
Unix Java Linux
Runtime.exec方法之获取process id
Runtime.exec方法之获取process id
168 0
|
Shell C++
C++中的exec()函数
exec()函数在C++中是一个进程控制函数,用于创建新进程执行其他程序或命令行指令。exec()函数可以替换当前进程的代码和数据,创建新的进程运行其他程序。exec()函数有多个版本,例如execl、execv、execle、execve等,根据不同的参数类型和个数来使用。
145 0
|
关系型数据库 MySQL 数据库
Mysql_1 Command Line Client 的使用,及常用命令
学习于:b站 骆昊 jackfrued 老师的网课+黑马网课
296 0
Mysql_1 Command Line Client 的使用,及常用命令
|
NoSQL MongoDB 数据安全/隐私保护
OCI runtime exec failed: exec failed: unable to start container process: exec: "mongo": executable file not found in $PATH: unknown
OCI runtime exec failed: exec failed: unable to start container process: exec: "mongo": executable file not found in $PATH: unknown
1009 0
OCI runtime exec failed: exec failed: unable to start container process: exec: "mongo": executable file not found in $PATH: unknown
|
物联网 Linux 开发者
Exec 之后文件描述特点|学习笔记
快速学习 Exec 之后文件描述特点
115 0
|
Ubuntu Linux 应用服务中间件
OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "ip": executable file not found in $PATH: unknown (Docker容器没有ip addr命令:exec ip addr 报错)
OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "ip": executable file not found in $PATH: unknown (Docker容器没有ip addr命令:exec ip addr 报错)
3518 0
check_user_createdate.sh
在前面这篇文章Linux如何找出用户的创建时间里面讨论了查看用户创建时间的方法,后面自己尝试弄了一个脚本来检查所有用户创建时间脚本,当然更合理的应该叫检查所有用户的密码修改时间比较准确(因为这种方法有条件限制),期间和夕照讨论了一下如何用shell脚本实现,获益良多。
631 0
|
Windows 关系型数据库 PostgreSQL