1

こんにちは、子プロセスと親プロセスを作成する単純な機能があります。

子プロセスは、dd if=/some/file of=/somedisk を実行すると仮定します。親プロセスは、(子が存在するまで) ループで実行され、子プロセスの dd に進行状況データを報告するよう強制するシグナル SIGUSR1 を送信することを想定しています。

もちろん、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()指定されたコマンドを実行する子プロセスを作成するため、ここには実際には 3 つのプロセスがあります。

  1. 親プロセス (ループのあるプロセス)
  2. 子プロセス (呼び出すプロセスsystem()
  3. ddプロセス_

ddプロセスではなく、子プロセスにシグナルを送信しています。SIGUSR1 はデフォルトでプロセスを終了させるため、子プロセスを強制終了しています。

これを修正するには、 を呼び出す代わりに、関数の 1 つを使用してddを実行できます。execsystem()

{   // 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プロセスになるため、2 つのプロセスしかありません。親が子にシグナルを送ると、シグナルはddに送られます。

ここには競合状態があることに注意してください。親プロセスは、 ddが開始してそのシグナル ハンドラを設定する前に、SIGUSR1 シグナルを送信する場合があります。堅牢であるためには、何らかの方法でこれを処理する必要があります。

于 2013-10-17T17:56:34.500 に答える