4

一度に許可される何かの同時実行数を制御するラッパーを Linux で作成しようとしています。そのために、システム全体のカウント セマフォを使用しています。セマフォを作成し、 を実行しsem_wait()、子プロセスを起動してから、子プロセスがsem_post()終了したときに実行します。それは結構です。

問題は、このラッパーに送信されたシグナルを安全に処理する方法です。シグナルをキャッチしない場合、コマンドは を実行せずに終了しsem_post()、セマフォ カウントが永続的に 1 つ減少する可能性があります。だから、私はシグナルハンドラーを作成しましたsem_post(). しかし、それでも問題があります。

が実行される前にハンドラーがアタッチされている場合、が完了sem_wait()する前にシグナルが到着し、がなくても が発生する可能性があります。シグナルハンドラを設定する前に行うと、逆のことが可能です。sem_wait()sem_post()sem_wait()sem_wait()

明らかな次のステップは、ハンドラーと のセットアップ中にシグナルをブロックすることでしたsem_wait()。これは私が今持っているものの擬似コードです:

void handler(int sig)
{
  sem_post(sem);
  exit(1);
}

...
sigprocmask(...);   /* Block signals */
sigaction(...);     /* Set signal handler */
sem_wait(sem);
sigprocmask(...);   /* Unblock signals */
RunChild();
sem_post(sem);
exit(0);

現在の問題は、sem_wait()缶がブロックされ、その間、信号がブロックされることです。プロセスを強制終了しようとするユーザーは、最終的に「kill -9」に頼る可能性があります。これは、何があってもそのケースを処理できないため、推奨したくない動作です。sem_trywait()短時間使用してテストすることもできますsigpending()が、セマフォで最も長く待機しているプロセスが次に実行されるという保証がなくなるため、公平性に影響します。

セマフォの取得中にシグナルを処理できる本当に安全なソリューションはありますか? 「セマフォがありますか」グローバルに頼ってシグナルブロッキングを削除することを検討していますが、セマフォを取得してグローバルを設定することはアトミックではありませんが、待機中にシグナルをブロックするよりは良いかもしれないため、100%安全ではありません。

4

3 に答える 3

7

sem_wait()信号がブロックされる原因は確かですか? そうではないと思います。のマニュアルページにsem_wait()は、シグナルによって中断された場合にEINTRエラーコードが返されると書かれています。sem_wait()

このエラー コードを処理できるはずです。そうすれば、シグナルが受信されます。信号が受信されないケースに遭遇したことがありますか?

返される可能性のあるエラーコードを確実に処理してくださいsem_wait()。まれかもしれませんが、100% 確実にしたい場合は、100% のベースをカバーする必要があります。

于 2009-06-01T23:39:37.737 に答える
0

問題に正しく取り組んでいますか?子が終了するのを待ちたい場合は、waitpid()システムコールを使用することをお勧めします。sem_post()あなたが観察したように、子供が信号を受信する可能性がある場合、子供がそうすることを期待することは信頼できません。

于 2009-06-02T00:04:22.443 に答える
0

これが古いことは承知していますが、Google の厚意により、まだこの記事を読んでいる人のために...

この問題に対する最も単純な (そして唯一の?) 堅牢な解決策は、System V セマフォを使用することです。これにより、プロセスがどのように終了しても、カーネルによって自動的に返される方法でクライアントがセマフォ リソースを取得できます。

于 2012-10-11T22:40:02.223 に答える