将系统和 POPEN 调用替换为不克隆进程内存的调用

replace system and popen calls with calls that does not clone process memory

本文关键字:调用 进程 内存 系统 POPEN 替换      更新时间:2023-10-16

我正在编写宽度内存和性能敏感的多线程服务器。因此,我需要标准system()popen()调用的替代方案,该调用不使用克隆通常需要太多时间的所有进程内存的fork()

似乎,需要使用vfork()然后execve()才能制作它。

有人可以帮我两个功能:

  • 替换system()呼叫。行为示例:一个线程调用函数来执行例如touch filename并调用线程等待执行结束。(所有其他线程必须继续工作)
  • 替换popen()调用 行为示例:相同的行为,但需要获取命令的输出,例如ls -flags (此代码的替代方法:正确代码 - 带 popen 的非阻塞管道)

谢谢

这只是有关如何处理您提出的解决方案的建议。对于您要询问的两个具体操作:

  • touch :您可以通过打开和关闭要触摸的文件来实现类似的效果
    • 注意不要在open上使用 O_TRUNC 标志
  • ls :这有点痛苦,因为您需要在 POSIX 系统上使用 dirent.h,并走
    • opendir
    • readdir
    • 完成后请务必致电closedir

如果您想使用 vforksystempopen调用替换为等效的调用,则需要注意。vfork调用使用起来有点棘手,因为如果孩子在调用后立即执行除exec以外的任何操作,则有可能破坏父级的内存状态。

为了您的替代system

  • 创建一个帮助程序来执行参数中提供的字符串
    • 帮助程序可以对提供的参数调用system,也可以分析命令字符串并调用exec
  • system替换函数中,创建一个 arg 向量来调用帮助程序,并将您真正想要执行的程序字符串作为参数传递给该程序
  • 调用vfork后,您立即在孩子中exec帮助程序
  • 家长等待孩子完成

在您的popen更换中:

  • 创建一个帮助程序,该程序接受stdoutstdin文件描述符作为参数,以及要执行的命令的字符串
    • 帮助程序会将传递的描述符重复为 01(或两者),如参数所示
    • 帮助程序可以使用父级和子级之间的popen和代理数据执行字符串,或者在分析命令字符串后调用exec
  • popen 替换函数中,使用 pipe 创建stdoutstdin通信通道(根据第二个 popen 函数参数),并创建一个 arg 向量来调用帮助程序,传入相应的文件描述符编号和命令字符串作为参数
  • 呼叫vfork后,您立即exec孩子中的帮助程序
  • 您需要一个pclose替代品才能获得子进程
Another way is to use the "fork()" with "execvp()" in child process. as mentioned by @jxh
int pid = fork();
if( pid == 0)
{
// In child process
  // redirect stderr/stdinput/stdoutput
  // prepare the execution command
  //use the exec() family of functions as per specific requirement.
}
else
{
// In parent process
  // check for open pipes and close the Std Output/Input/Error pipes.
}

详细信息参考

https://www3.physnet.uni-hamburg.de/physnet/Tru64-Unix/HTML/APS33DTE/DOCU_004.HTM