execv()价格昂贵吗?

时间:2015-09-25 15:08:32

标签: c linux unix kernel ipc

我有一个要求。我的进程必须在其代码路径之一中执行另一个进程。子进程运行一些检查,当某些条件为真时,它必须重新执行。当我在高端机器上测试时,它没有引起任何性能问题。

但是在同一个进程中再次调用execv()会很昂贵吗?特别是当它自己执行时?

注意:第二次没有涉及fork()。该过程将第二次execv()本身,以在其虚拟地址空间中重新映射。

2 个答案:

答案 0 :(得分:4)

第二次execv()电话并不比第一次更贵。它甚至可能更便宜,因为系统可能不需要从磁盘读取程序映像,也不需要加载任何新的动态库。

另一方面,execv()只需在同一程序中进行分支即可。我无法想象一种情况,我想写一个重新执行自己的程序(没有分叉),而不是仅仅调用一个函数。

第三方面,"便宜"并且"昂贵"是相对的。除非你这么做很多,否则你可能实际上没有注意到任何差异。

答案 1 :(得分:4)

execve系统调用有点贵;运行它超过几十次 - 或者每秒几百次(即使它可能持续几毫秒,也许大部分时间可能只有几分之一毫秒)是不合理的。

它可能比你用来mmap(2)(& munmap& mprotect(2)}和setcontext(3)的十几个等效来电更快(更干净) 几乎模仿它(然后,有一个问题是在执行execve的人之外杀死正在运行的线程,以及附加到进程的其他资源,例如FD_CLOEXEC - ed文件描述符)。

(您将无法复制mmapmunmapsetcontextclose正是execve正在做的事情,但是你可能足够接近......但这太荒谬了)

此外,execve实际成本还应考虑共享库的动态加载(应在运行main之前加载),但技术上 execve系统调用...)及其启动后。

问题可能并不多,这在很大程度上取决于机器的实际状态和execve ed executabe。我猜execve是一个巨大的ELF二进制文件(一些可执行文件可能有一个千兆字节的代码段,例如传说神秘的Google爬虫可能是一个单片程序,有十亿个C ++源代码行,在某些时候它是静态链接),例如数百个共享库比execve要长/bin/sh

我想同时,来自具有TB级地址空间的进程的execve比我execve我的zsh shell在我的桌面上执行的时间要长得多。

execve自己的程序(实际上是它的一些更新版本)的一个典型原因是,在一个持久的服务器中,当服务器的二进制可执行文件已经更新时。

execve自己的程序的另一个原因是让一个或多或少的“无状态”服务器(一些用于静态内容的Web服务器)重新启动并重新加载其配置文件。

更一般地说,这是一个完整的研究主题:阅读dynamic software updatingapplication checkpointingpersistence等...另请参阅参考文献here

转储core(5)文件是一样的:在我的生活中,我从来没有看到核心转储持续时间超过一秒钟,但我确实听说过比1990年代早期的Cray计算机, core转储可能(病理上)持续半小时......所以我想一些病态的execve可能会持续相当长的时间(例如,使用C-O-W带来一个TB的代码段RAM中的技术;这不算作execve时间,但它是启动程序的成本的一部分;并且您可能还有许多共享库的重定位。)。

附加物

对于一个小的可执行文件(少于几兆字节),你可能每秒可以承受几百execve个,所以这在实践中并不是什么大问题。请注意,使用lsmv等常用命令的shell脚本是execve - 非常多(通常在fork之后,它会为几乎所有命令)。如果您怀疑某些问题,可以进行基准测试(例如使用strace -tt -T -f使用strace(1) ....在我的桌面上Debian / x86-64 / Sid i7 3770K execve /bin/lsstrace --T -f -tt zsh-static -c ls}大约需要250μs(对于ELF二进制文件executable /bin/ls的118K字节(可能已经在page cache中),而ocamlc(1.8Mbyte的二进制)约为1.3ms; a malloc通常需要一半或几μs;对time(2)的调用大约需要3ns(通过vdso(7)来避免系统调用的开销......)

相关问题