一度に許可される何かの同時実行数を制御するラッパーを 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%安全ではありません。