如何在子进程结束后立即捕获它?

how to catch a child process as soon as it ends?

我写了一个使用 fork 的复制函数,以便在后台创建函数 运行, 子进程应该复制文件,父进程不会等待子进程完成, 我的问题是我想在子进程完成复制文件时打印 " copying was complete " massage ,但我不知道如何在子进程结束时立即捕获它 蚂蚁帮助?

void copyFunction::execute() {

    char *buff = new char[1024]();
    int fdRead = open(args[1], O_RDONLY);
    if (fdRead == -1) {
        perror(" error: open failed");
        return;
    }

    int fdWrite = open(args[2], O_WRONLY | O_TRUNC);
    if (fdWrite ==-1) {                // if we couldn't open the file then create a new one (not sure if we supposed to this ?)
        fdWrite = open(args[2], O_WRONLY | O_CREAT, 0666);
        if (fdWrite == -1) {
            perror(" error: open failed");
            return;
        }
    }

    PID = fork();
    if (PID == 0) {
        setpgrp();

        int count = read(fdRead, buff, 1);  /// read from the file fd1 into fd2
        while (count != -1) {
            if (!count) {
                break;
            }
            if (write(fdWrite, buff, 1) == -1) {
                perror(" error: write failed");
                return;  // not sure if we should return
            }
            count = read(fdRead, buff, 1);
            if (count == -1) {
                perror(" error: read failed");
                exit(1) ;
            }
        }
        exit(1) ;
    }  if (PID > 0) { 
            SmallShell::getInstance().Jobs_List.addJob(SmallShell::getInstance().currentCommand, false);
            return;

    } else {
        perror(" error: fork failed");
    }
}

去哪里打电话?

 cout << "copying was complete" << endl;

使用 wait() 调用。

PID = fork();
if(PID > 0){
    wait(NULL);
    cout << " copying is complete" << endl;

}

这是一个相当广泛的主题,可以通过多种方式来完成。当一个进程终止时,它的父进程会收到一个 SIGCHLD 信号。您可以使用 sigaction() 为此设置一个信号处理程序(旧的 C/C++ 代码也为此使用旧的 signal() 函数)。

该方法的主要问题是整个 C/C++ 库完全脱离了在信号处理程序中运行的任何代码。 None 其中是信号安全的。不能碰它。不能用。除了直接调用操作系统外,您不能在信号中做任何事情。好吧,如果没有很多痛苦和眼泪,你就无法做任何其他事情。

但对于大多数简单的用例来说,这可能就足够了。

但如果你确实需要更多的喘息空间,你就必须做更多的工作。在 Linux 上,您可以使用 signal file descriptor that, pretty much, turns the signal into a file that can be read in an orderly, organized fashion. On BSD you can use kqueue notifications 来做同样的事情。这种方法的一个相当粗略的模拟是创建一个普通的花园品种 pipe()。您提前创建它,并使用一个普通的信号处理程序将一个字节写入管道(它可以使用 write() 系统调用直接执行)。在这两种情况下——成熟的信号处理程序,或使用 interla 管道的苍白模仿——您的主应用程序可以使用 poll() 来知道何时收到信号,这意味着您的子进程已终止。或者您的主应用程序可以使用专用于该目的的执行线程。

你们终于可以庆祝了。工作量很大,不是吗?