2016-05-23 7 views
5

私は親プロセスを持っており、子プロセスをほとんど作成していません。私が見つけた最も良い方法はfork + execlです。しかし親プロセスは、具体的な子のexeclが失敗するかどうかを知る必要があり、それを実装する方法はわかりません。linuxで子プロセスを作成し、失敗する可能性がある場合の最良の方法

 int pid = fork(); 
     if (pid < 0) { 
      std::cout << "ERROR on fork." << std::endl; 
     } if (pid == 0) { 
      execl("/my/program/full/path", (char *)NULL); 
      exit(1); 
     } 
     else { 
      if (/*child's process execl fails*/) { 
       std::cout << "it failed" << std::endl 
      } else { 
       std::cout << "child born" << std::endl 
      } 
     } 

私はこのアイデアが良くないと思う:

int status(0); 
sleep(100); 
int res = waitpid(pid, &status, WNOHANG); 
if (res < 0 && errno == 10) { 
    std::cout << "it failed" << std::endl 
} else { 
    std::cout << "child born" << std::endl 
} 

それは子プロセスが100ミリ秒後に死ぬことを願っていて良いではありませんので、私はその意志が起こるように確かにそれを知りたいです。

また、このようなチェックのためのshared_memoryまたは特別なパイプ接続の作成は、Beesに対するCannonです。

私はまだ見つからなかったという単純な解決策が必要です。

これを達成する最も良い方法は何ですか?

+0

'popen'を使用して戻り値を確認してください。 – Andrew

+0

それはまだ生きていると言えば、execlが失敗していないことをどのように確認できますか?たぶんそれは失敗し、 'exit(1)'命令をまだ完了していないという理由だけでプロセスは生きています。 – Arkady

+0

あなたのプロセスが正常に起動したことを確認したいのですか*完了し*してステータスがゼロ*を返していますか? 2つは全く異なっています。 – Andrew

答えて

1

一般的な解決策として、シグナルハンドラ(SIGUSR1)をsigaction()を使用して親に登録することができます。

子:unregisterシグナルハンドラで、execl()呼び出しが失敗した場合、SIGUSR1を親に送信する必要があります。

親では:すべての子のpidはstd :: setに格納します。すべての子が作成されると、子を追跡するために別のスレッドを作成するだけです。スレッド関数では、単にwait()を呼び出し、セットからpidを削除します。 SIGCHLDシグナルを聞くもう1つの方法(しかし、より複雑な解決策につながるので、別のスレッドを生成する場合はスレッドを使用するオプションです)。

セットが空の場合は行っています。

+0

それは良い汎用ソリューションのように見えます。私は特別な信号なしでそれについて考えましたが、信号でそれは論理的に完成したように見えます。ありがとうございました。 – Arkady

関連する問題