在分叉时执行外部程序是不可取的

Let*_*_Be 1 c linux posix

我有一个大的服务器软件,可以占用4-8GB的内存.

这使得fork-exec很麻烦,因为fork本身可能需要很长时间,而且默认行为似乎是fork将失败,除非有足够的内存用于整个驻留内存的副本.

因为在开始分析时,我开始表现为最热门的地方(60%的时间花在分叉上),我需要解决它.

避免fork-exec例程的最简单方法是什么?

Bas*_*tch 6

你基本上不能避免fork(2)(或等效的clone(2)系统调用...,或者vfork我不推荐使用的过时)+ execve(2)来启动外部命令(àlasystem (3),或点菜的posix_spawn在Linux和(可能)的MacOSX和其他大多数Unix或POSIX系统).

是什么让你认为它正在成为一个问题?今天8GB进程虚拟地址空间并不是什么大问题(至少在8Gbytes或16GB内存的机器上,就像我的桌面一样).由于所有最近的Unix和Linux都使用了懒惰的写时复制技术,因此实际上你不需要两倍的RAM(但你需要交换空间).

也许您可能认为交换空间可能是一个问题.在Linux上,您可以通过交换文件来添加交换空间; 只是以root身份运行:

 dd if=/dev/zero of=/var/tmp/myswap bs=1M count=32768
 mkswap /var/tmp/myswap
 swapon /var/tmp/myswap
Run Code Online (Sandbox Code Playgroud)

(当然,确保这/var/tmp/不是一个tmpfs挂载的文件系统,但是坐在某个磁盘上,也许是一个SSD ....)

当你不再需要大量的交换空间时,运行swapoff /var/tmp/myswap....

您也可以在程序开头附近启动一些外部shell进程(àla popen),然后可以向它发送shell命令.看看我的execicar.c程序获取灵感,或者如果它适合使用它(我10年前为了类似的目的写了它,但我忘记了细节)

或者在程序开头派一些解释器(Lua,Guile ......)并向它发送一些命令.

每秒运行超过几十个命令 (启动任何外部程序)是不合理的,应该被视为设计错误,恕我直言.也许你正在运行的命令可以通过进程中的功能所取代(例如,/bin/ls是可以做到的stat,readdir,glob 功能 ...).也许您可以考虑在代码中添加一些插件功能(使用dlopen(3)&dlsym)(并从插件运行函数,而不是经常启动相同的程序).或者也许在您的代码中嵌入一​​个解释器(Lua,Guile,...).

例如,对于Web服务器,查找旧的CGIFastCGI或HTTP转发(例如URL重定向)或嵌入式PHPHOPOcsigen