我正在编写一个小程序,它有点像服务器产生其客户端程序(本地,而不是通过网络),并在它们之间做有趣的事情。虽然我使用的主要操作系统是Linux,但我希望它可以在包括Windows在内的其他操作系统上运行。有fork
和exec
可以完成这项工作,但是当我通过cygwin将程序移植到Windows时,我不希望在cygwin中实现的那个糟糕的fork
可以启动,实际上调用CreateProcess
并使用带有共享内存互斥锁的setjmp
/ longjmp
将当前进程的内存区域复制到新进程,所有这些都是为了替换为另一个程序({{1} })。在阅读cygwin的FAQ页面时,我发现了exec
及其spawn.h
,它在Windows中基本上看起来像posix_spawn
。它似乎是一个新功能(...我的意思不是原始的UNIX系统功能之一),所以我对它有一些问题。
广泛实施得好吗? (我在网上看到一些帖子没有在他/她的系统下定义。)
在Linux中使用CreatePorcess(Ex)
代替posix_spawn
/ fork
可以预期会有任何性能提升或恶化吗?
为什么exec
与posix_spawn
/ fork
相比,exec
的知名度较低且使用率较低,但自1999年以来一直是标准的?
答案 0 :(得分:1)
根据Linux man pages,它出现在2000年发布的glibc 2.2版中,该实现符合POSIX.1-2001和POSIX.1-2008。我希望至少在任何至少使用此glibc版本的平台上都支持它,因为它的行为至少可以在这些平台上使用fork
+ exec
进行模拟。
在Linux上,如果使用fork
代替exec
,您可能会比vfork
/ fork
略微提升性能:
当满足以下任一条件时,使用vfork(2)而不是fork(2)创建子进程:
- attrp指向的属性对象的spawn-flags元素包含GNU特定的标志POSIX_SPAWN_USEVFORK;或
- file_actions为NULL且attrp指向的attributes对象的spawn-flags元素不包含POSIX_SPAWN_SETSIGMASK,POSIX_SPAWN_SETSIGDEF,POSIX_SPAWN_SETSCHEDPARAM, POSIX_SPAWN_SETSCHEDULER,POSIX_SPAWN_SETPGROUP或POSIX_SPAWN_RESETIDS。
换句话说,如果调用者请求了vfork(2),或者在exec(3)执行请求的文件之前,子节点中没有预期的清理,则使用vfork(2)。
答案 1 :(得分:1)
posix_spawn
不广泛实施,但无论如何都应该使用它。
如果一个平台缺乏它,它总是很容易使用直接替换,只做fork-and-exec。
如果"原生" /最佳实施可用(作为系统的一部分,或者是特定于插入式平台的实施),它将对{{ {1}}价格昂贵,对于根本无法fork
的系统而言更是如此(MMU-less系统,没有cygwin之类的Windows等)。
即使在fork
是原生的"快速"的系统上,如果父母有很多虚拟映射,它仍然会相当慢,而且速度稍慢即使对于小父母而言,也不是最佳fork
。请参阅此Twitter主题以获取一些调查结果:https://twitter.com/RichFelker/status/602313644026761216
至于为什么它没有得到更广泛的使用/实施,它可能是一个不广为人知的混合体,以及相当笨重,无偿的面向对象的API设计。
答案 2 :(得分:0)
- 广泛实施得好吗? (我在互联网上看到一些帖子没有在他/她的系统下定义。)
醇>
高级实时XSI选项组是可选的,因此您可以符合POSIX,而不是实现它。但是对于GNU / Linux,你现在可以指望它可用。
- 在Linux中使用posix_spawn而不是fork / exec,我可以期待性能提升或恶化吗?
醇>
可能是的,对于大型进程quite some time,只能在exec
时丢弃复制页表。 posix_spawn
类似musl或glibc的实现尽可能使用vfork(2)
(或clone(2)
直接)以避免这种情况。对于像cygwin这样的系统,fork
emulated的成本相当高,posix_spawn
大大降低了开销。
- 为什么posix_spawn比fork / exec更少知道和使用,尽管自1999年以来一直是标准的?
醇>
惯性,我猜。