4

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

看来,需要用vfork()the ​​nexecve()来制作。

有人可以帮助我完成两个功能:

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

谢谢

4

2 回答 2

3

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

  • touch:可以通过打开和关闭要触摸的文件来达到类似的效果
    • 小心不要在上面使用O_TRUNC标志open
  • ls: 有点痛苦,因为你需要dirent.h在POSIX系统上使用,并且走结果
    • opendir
    • readdir
    • closedir完成后一定要打电话

如果您想用等效的 using替换systemand调用,则需要小心。这个调用使用起来有点棘手,因为如果孩子在调用之后做任何事情,你就有可能破坏父母的记忆状态。popenvforkvforkexec

为了您的替换system

  • 创建一个帮助程序来执行参数中提供的字符串
    • 帮助程序既可以调用system提供的参数,也可以解析命令字符串并调用exec
  • 在您的system替换函数中,创建一个 arg 向量来调用帮助程序并传入您真正想要执行的程序字符串作为该程序的参数
  • 在你打电话后vfork,你立即exec在孩子的助手程序中
  • 父母等待孩子完成

在您的popen替代品中:

  • stdout创建一个接受和stdin文件描述符作为参数 的帮助程序,以及您要执行的命令的字符串
    • 助手程序将把传入的描述符复制到01(或两者),如参数所示
    • 辅助程序可以使用popen父子之间的代理数据来执行字符串,也可以exec在解析命令字符串后调用
  • 在您的popen替换函数中,用于pipe创建stdoutstdin通信通道(根据第二个popen函数参数)并创建一个 arg 向量来调用帮助程序,传入适当的文件描述符编号和命令字符串作为参数
  • 在你打电话后vfork,你立即exec在孩子的帮助程序
  • 您需要pclose替换才能获得子进程
于 2012-06-11T21:41:03.533 回答
0
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

于 2019-11-13T14:07:33.533 回答