将系统和 POPEN 调用替换为不克隆进程内存的调用
replace system and popen calls with calls that does not clone process memory
我正在编写宽度内存和性能敏感的多线程服务器。因此,我需要标准system()
和popen()
调用的替代方案,该调用不使用克隆通常需要太多时间的所有进程内存的fork()
。
似乎,需要使用vfork()
然后execve()
才能制作它。
有人可以帮我两个功能:
- 替换
system()
呼叫。行为示例:一个线程调用函数来执行例如touch filename
并调用线程等待执行结束。(所有其他线程必须继续工作) - 替换
popen()
调用 行为示例:相同的行为,但需要获取命令的输出,例如ls -flags
(此代码的替代方法:正确代码 - 带 popen 的非阻塞管道)
谢谢
这只是有关如何处理您提出的解决方案的建议。对于您要询问的两个具体操作:
-
touch
:您可以通过打开和关闭要触摸的文件来实现类似的效果- 注意不要在
open
上使用O_TRUNC
标志
- 注意不要在
-
ls
:这有点痛苦,因为您需要在 POSIX 系统上使用dirent.h
,并走-
opendir
-
readdir
- 完成后请务必致电
closedir
-
如果您想使用 vfork
将system
和popen
调用替换为等效的调用,则需要注意。vfork
调用使用起来有点棘手,因为如果孩子在调用后立即执行除exec
以外的任何操作,则有可能破坏父级的内存状态。
为了您的替代system
:
- 创建一个帮助程序来执行参数中提供的字符串
- 帮助程序可以对提供的参数调用
system
,也可以分析命令字符串并调用exec
- 帮助程序可以对提供的参数调用
- 在
system
替换函数中,创建一个 arg 向量来调用帮助程序,并将您真正想要执行的程序字符串作为参数传递给该程序 - 调用
vfork
后,您立即在孩子中exec
帮助程序 - 家长等待孩子完成
在您的popen
更换中:
- 创建一个帮助程序,该程序接受
stdout
和stdin
文件描述符作为参数,以及要执行的命令的字符串- 帮助程序会将传递的描述符重复为
0
或1
(或两者),如参数所示 - 帮助程序可以使用父级和子级之间的
popen
和代理数据执行字符串,或者在分析命令字符串后调用exec
- 帮助程序会将传递的描述符重复为
- 在
popen
替换函数中,使用pipe
创建stdout
或stdin
通信通道(根据第二个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
相关文章:
- 为什么创建进程 API 调用会导致内存访问冲突?
- 父进程中的挂钩 api 调用
- 使用 Node.js 调用child_process与从 C 调用子进程并创建C++绑定以从 node.js 调用
- 使用参数调用远程进程中的函数(注入的 DLL)
- 在x64进程中调用x86 winapi函数
- 在调用进程的上下文中通过 win32 执行批处理,从而保留环境变量
- 如何使超链接调用相同的C++CGI进程
- 子输出出现在主进程使用 system() 调用它之前
- 从注入进程的 DLL 调用函数并更改指针函数的地址
- 在POSIX中,我可以保存信号以供调用条件等待的其他线程使用吗.(这些线程来自同一进程)
- 关闭Qt控制台应用程序会终止exec()调用中的进程,并且无法从main()扩展到范围
- 从库中定义的进程调用静态函数
- 使用Spark调用进程外dll函数
- 如何使用MPI库仅为进程的子集调用(c++)函数
- 从另一个进程调用 SetDllDirectory 不起作用?
- 可以调用 HtmlHelp API 并将所有权传递给另一个进程
- 可以单独调用两个 CreateProcess() 共享相同的启动和进程信息
- 如何在 ATL COM+ 进程外服务器应用程序中标识调用方的进程?
- 将系统和 POPEN 调用替换为不克隆进程内存的调用
- DLL / SO库,库内存与调用进程的关系如何?