1

嗨我有一个简单的功能,我创建一个子进程和父进程。

子进程假设运行 dd if=/some/file of=/somedisk。父进程假设在循环中运行(直到子进程存在)并发送信号 SIGUSR1,该信号强制子进程中的 dd 报告进度数据。

当然,我有管道,可以将 stdio 和 stderr 从子级重定向到父级。(我在其他功能中使用它,它工作正常)

我遇到的问题是: 1. 我的 stderr 上什么也没有;2. 一旦我发送 SIGUSR1,进程就会以某种方式退出。

    if(my_pid>0) //The parent part
            {

            close(FD_pipe_stdout[1]);// Parent process closes output side of the pipe 
            close(FD_pipe_stderr[1]);// Parent process closes output side of the pipe                               
            while(0==waitpid(my_pid, &my_pid_status, WNOHANG))
                {
                kill(my_pid, SIGUSR1); 
                sleep(1);
                //read(FD_pipe_stderr[0], pipe_error,PIPE_MAX_SIZE); // Read in a string from the stderror
                //puts(pipe_error);

                }
            puts("going out");
            read(FD_pipe_stdout[0], pipe_output,PIPE_MAX_SIZE); // Read in a string from the pipe's input side

            close(FD_pipe_stdout[0]);//on the end close the other side of pipe
            close(FD_pipe_stderr[0]);//on the end close the other side of pipe
            }         
   else
            {   // The child part
            close(FD_pipe_stdout[0]);/* Child process closes input side of the pipe */
            close(FD_pipe_stderr[0]);/* Child process closes input side of the pipe */
            dup2(FD_pipe_stdout[1],1); //redirect the stdout(1) to the fd_pipe and then close the sdtout
            dup2(FD_pipe_stderr[1],2);//redirect also stderr to the pipe
            system(dd if=/image.img of=/dev/sda);
            close(FD_pipe_stdout[1]); //on the end close the other side of pipe
            close(FD_pipe_stderr[1]); //on the end close the other side of pipe
            exit(0);
            }

我在屏幕上看到父母正在退出 while 循环,但我不明白为什么。

提前致谢

4

1 回答 1

4

system()创建一个子进程来运行指定的命令,所以这里真的有三个进程:

  1. 父进程(有循环的那个)
  2. 子进程(调用system()
  3. dd进程_

您正在向子进程发出信号,而不是dd进程。SIGUSR1 默认情况下会导致进程退出,因此您正在杀死子进程。

要解决此问题,您可以使用其中一个函数运行ddexec,而不是调用system()

{   // The child part
    close(FD_pipe_stdout[0]);
    close(FD_pipe_stderr[0]);
    dup2(FD_pipe_stdout[1],1);
    dup2(FD_pipe_stderr[1],2);
    execlp("dd", "dd", "if=/image.img", "of=/dev/sda", NULL);
    perror("exec failed");
    exit(1);
}

现在你只有两个进程,因为子进程变成了dd进程。当父母向孩子发出信号时,信号将转到dd

请注意,这里有一个竞争条件。父进程可能会在dd启动并设置其信号处理程序之前发送 SIGUSR1 信号。为了变得健壮,你应该以某种方式处理这个问题。

于 2013-10-17T17:56:34.500 回答