unix c++ fork()& execl()不等待,完全分离

0h4hbjxa  于 2023-06-22  发布在  Unix
关注(0)|答案(3)|浏览(204)

所以我有一个简单的fork和exec程序。它工作得很好,但我希望能够分离启动的进程,我尝试了一个没有等待的fork:

if((pid = fork()) < 0)
    perror("Error with Fork()");
else if(pid > 0) {
    return "";
}
else {
    if(execl("/bin/bash", "/bin/bash", "-c", cmddo, (char*) 0) < 0) perror("execl()");
    exit(0);
}

它启动进程很好,但当我的主应用关闭时,我的分叉进程也是如此。
在主进程(启动它的)关闭后,我如何保持分叉进程运行?
Thanks:D

kiayqfof

kiayqfof1#

如果你想启动一个detached/daemon进程,可以做以下几件事:

  • 再次fork并退出第一个子进程(这样第二个子进程就不再把原来的进程作为它的父进程pid)
  • 调用setsid(2)获取新的会话和进程组
  • 重新打开stdin/stdout/stderr取消引用控制tty(如果有)。或者,例如,您可能继承了一个管道stdout,如果您尝试编写它,它将被破坏并给予SIGPIPE。
  • chdir到/以离开祖先的当前目录
to94eoyn

to94eoyn2#

也许你真正想要的是忽略你的fork()进程中的SIGHUP,因为这通常是导致程序崩溃的原因。也就是说,你需要做的是

signal(SIGHUP, SIG_IGN);

使用nohup安排一个读取器,这将避免可能的写入关闭管道。为了避免这种情况,您可以安排标准输出不可用,或者忽略SIGPIPE。有许多信号在未忽略时终止程序(参见man signal;一些信号不能被忽略),但是将被发送到孩子的信号是SIGHUP

hi3rlvi2

hi3rlvi23#

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 %d\n", 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 %d\n", id_spawn);
}

有2个源代码可以参考

  1. util-linux-2.xx.x/sys-utils/setsid.c
  2. busybox-1.xx.x/util-linux/setsid.c

相关问题