1

現在、C++ 内で小さなシェルを作成中です。

ユーザーは、 などのプロンプトでジョブを入力できますexe1 && exe2 &。BASH シェルと同様に、正常に終了したexe2場合にのみ実行します。exe1さらに、ジョブ全体をバックグラウンドで実行する必要があります (末尾の&演算子で指定)。

現在、ジョブの実行jobManagerを処理する とjob、ジョブの実行可能ファイルとそれらの個々の引数/条件を含む構造体があります。を呼び出してから、適切な引数を指定して呼び出すfork()と、ジョブが開始されます。ジョブが終了すると、どのプロセスが終了したかを判断するために実行するexecvp()のシグナル ハンドラーがあります。終了したら、その終了コードを観察し、 launch に進むべきかどうかを判断します。SIGCHLDwait()exe1exe2

私の懸念は、どのように起動するかですexe2。ハンドラーのコンテキストから jobManager の開始関数を使用すると、スタックにぶら下がっているハンドラー関数SIGCHLDが多すぎる可能性があるのではないかと心配しSIGCHLDています (たとえば、10 個の条件付き実行があった場合)。さらに、たとえそれが間接的に発生していたとしても、シグナルハンドラから次の実行を開始するのは良い考えではないようです。(1.5年前、シグナル処理について学んでいたときに、似たようなことをしようとしました-失敗したことを思い出しているようです)。

jobManager上記のすべてをバックグラウンドで実行できるようにする必要があり、忙しい状態で座っているだけで戻ってくるのを待っているのを避けたいと思いexe1ます。また、別のプロセスの実行を開始するのを待っているだけの別のスレッドを持たないようにしたいと思います。ただし、ハンドラーjobManagerから次のプロセスの実行を開始するように指示するのは、貧弱なコードのようです。SIGCHLD

フィードバックをお待ちしております。

4

2 に答える 2

1

私は2つの方法を見ます:
1)あなたのsighandlerを「sigwait」(man 3 sigwaitを参照)を呼び出すループに置き換えてからループに入れ
ます

2)パイプの作成を開始する前に、プログラムのメインループでパイプハンドルの「select」を使用してイベントを待機します。シグナルハンドラーではパイプに書き込み、メインループでは状況を処理します。

于 2011-11-13T01:25:57.347 に答える
0

うーん、いいね。

プロセスごとに1回、2回フォークするのはどうですか?最初のものが実行され、2番目のものが停止します。親SIGCHLDハンドラーで、必要に応じてSIGCONTを2番目の子に送信します。2番目の子は、オフになってジョブを実行します。当然、最初の1つを実行しない場合は、2番目のSIGKILLを実行します。これは、実際には何も設定していないため、安全です。

それはどのように聞こえますか?何もしないプロセスがありますが、それほど長くはかからないはずです。

于 2011-11-13T01:24:36.303 に答える