6

私は現在、C++で小さなシェルを書いています。

ジョブとそれに関連付けられたPIDは、ジョブポインタのキューに格納されます(job *)。新しいジョブが実行されると、そのジョブに関する情報がキューに追加されます。複数のジョブを同時に処理でき、シェルのコンソールでいつでも新しいジョブを入力できるため、終了するジョブを待機するシグナルハンドラーがあります。

ジョブが終了したら、その情報をアクティブなジョブキューから削除し、終了したジョブの両端キューに移動する必要があります。ただし、別のジョブが停止したときに、ユーザーの新しいジョブがキューに追加されている可能性があります。

そのような場合、それらのinsertキュー操作は中断され、私のシグナルハンドラーが呼び出され、そのpop操作が実行されます。

このプロセス中に破損が発生する可能性があると想像しているので、この潜在的な競合状態をどのように解決できるかを理解しようとしています。中断された親プロセスがその時点でキューを使用しているとデッドロックが発生するため、ミューテックスを使用できません。

C++11タスクレットに関する情報とともに、ユーザーが宣言したアトミック操作が可能であるという情報がいくつか表示されます。しかし、これらが私の質問に関連しているかどうかはわかりません。

興味深いことに、私が参照として使用しているサンプルシェル(MSH- http://code.google.com/p/mini-shell-msh/)は、そのような条件を処理していないようです。シグナルハンドラは、メインコンソールとともにジョブリストをすぐに変更します。おそらく私がここで見落としているものがありますか?

いつものように、すべてのフィードバックが適用されます。

4

2 に答える 2

4

競合状態を回避するには、いくつかの方法があります。

  • ジョブ ポインタにはウェイト フリー (アトミック) キューを使用します。
  • 他の種類のキューを使用しますが、sigprocmask(ハンドラー以外のコードで)呼び出しで適切なsa_mask値を使用して保護します。sigaction
  • シグナルハンドラーをまったく使用しないでください。同期的な方法でシグナルを処理できる移植性のないシステムコールを使用してください。Linux では可能ですがsignalfd、他のプラットフォームについては不明です。
于 2011-11-16T13:01:15.443 に答える
1

sigprocmask()非ハンドラ コードのクリティカル セクション周辺でシグナルを無効にする必要があります。これは、カーネル内のデバイス ドライバーがドライバーのユーザー側で割り込みを無効にし、割り込みハンドラーと共有される構造体を更新するのに似ています。

于 2011-11-16T04:20:10.187 に答える