c++fork,不需要等待,即可解压execl
c++ fork, without wait, defuncts execl
在c++中,想要派生一个不会挂起其父进程的进程——其父进程是一个守护进程,必须保持运行。如果我在forked进程上等待(),forked execl不会取消资助-但是-它也会挂起应用程序-不等待修复应用程序挂起-但是命令变为取消资助。
if((pid = fork()) < 0)
perror("Error with Fork()");
else if(pid > 0) {
//wait here will hang the execl in the parent
//dont wait will defunt the execl command
//---- wait(&pid);
return "";
} else {
struct rlimit rl;
int i;
if (rl.rlim_max == RLIM_INFINITY)
rl.rlim_max = 1024;
for (i = 0; (unsigned) i < rl.rlim_max; i++)
close(i);
if(execl("/bin/bash", "/bin/bash", "-c", "whoami", (char*) 0) < 0) perror("execl()");
exit(0);
}
在execl的命令不会失效的情况下,我如何在没有等待(&pid)的情况下分叉execl?
更新通过在分叉之前添加以下内容修复
signal(SIGCHLD, SIG_IGN);
仍在利用我有限的技能,在公认答案的基础上找到一个更兼容的解决方案。谢谢
默认情况下,wait
和朋友会等待进程退出,然后收获它。如果没有子进程退出,您可以用WNOHANG
调用waitpid
以立即返回。
失效的/"僵尸"进程将一直存在,直到你在它上wait
。因此,如果你在后台运行它,你必须安排最终通过以下几种方式获得它:
- 常规试用
waitpid
和WNOHANG
:int pid = waitpid(-1, &status, WNOHANG)
- 为
SIGCHLD
安装一个信号处理程序,以便在其退出时得到通知
此外,在POSIX.1-2001下,可以使用sigaction
在SIGCHLD
上设置SA_NOCLDWAIT
。或者将其操作设置为SIG_IGN
。较旧的系统(包括Linux 2.4.x,但不包括2.6.x或3.x)不支持此功能。
检查您的系统手册页,或者在"单一Unix规范"中选择等待。Single Unix Spec还提供了一些有用的代码示例。SA_NOCLDWAIT
记录在sigaction中。
我认为信号处理程序将是所示的最佳方式。我想指出另一种处理方法:分叉两次,让孩子退出,而孙子会调用execl
。然后,init进程将清理已失效的进程。
正如注释中所说,双叉将进程从失效状态保存下来。
创建守护程序时执行双分叉的原因是什么?
EX1:当客户端不退出时,不等待
#include <spawn.h>
extern char** environ; //posix_spawn using environ that declare in glibc-2.xx/posix/environ.c
void main()
{
pid_t spawnid;
char param[64] = {0};
char* args[] = {"/usr/drive_server", param, NULL};
posix_spawn(&spawnid, "/usr/drive_server", NULL, NULL, args,
environ);
getchar();
}
EX2:当客户端退出时,等待子进程分离
#include <spawn.h>
extern char** environ;
void main()
{
pid_t spawnid;
char param[64] = {0};
pid_t sessionid;
char* args[] = {"/usr/drive_server", param, NULL};
posix_spawn(&spawnid, "/usr/drive_server", NULL, NULL, args, environ);
sessionid = 0;
while( sessionid != spawnid )
{
sessionid = getsid(spawnid);
printf("sessionid id %dn", sessionid);
usleep(200000);
}
}
//subprocess file
void main()
{
setsid(); //detach
getchar();
}
EX3:当系统有setsid命令时,不等待
#include <spawn.h>
extern char** environ;
void main()
{
pid_t id_spawn;
char* args[] = {"/usr/bin/setsid", "/volume1/drive_server", serviceName8, NULL};
posix_spawn(&id_spawn, "/usr/bin/setsid", NULL, NULL, args, environ);
printf("drive_server* spawn id %dn", id_spawn);
}
有两种源代码可以参考
- util-linux-2.xx.x/sys utils/setsid.c
- busybox-1.xx.x/util-linux/setsid.c
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有类似std::lower_bound的函数,而不需要排序/分区输入
- 为什么output_editor Concept不需要output_e迭代器标记
- 在除法中不需要四舍五入
- 与C代码相比,为什么C++代码不需要"#define _POSIX_C_SOURCE 200809L"?
- 将值从另一个数组写入数组,不包括不需要的值 C++
- C++ 写入路径名中包含不需要的空字符的文件
- 是否有必要获取锁并在不需要唤醒线程时通知condition_variable?
- 使用 assimp 加载模型 - 不需要提升?
- 为什么转换函数声明不需要至少一个定义类型说明符
- 返回不需要的值的二叉搜索程序
- 当我不需要数据库中的所有值时,如何部分初始化 c++ 对象?
- C++:用户输入会产生不需要的行为
- 如何在不需要LIBCD.lib的情况下在Visual Studio 6中编译C项目
- 为什么python需要全局关键字而C/C++不需要?
- 将一个宏传递到另一个宏而不是直接传递内容时会出现不需要的额外"空"参数
- 为什么我们需要在 C++ 中检查空指针,而在 Java 中不需要?
- 为什么复制构造函数不需要检查输入对象是否指向自身?
- 为什么不需要在 C++20 中的依赖类型之前指定"typename"?
- c++fork,不需要等待,即可解压execl