4

C++11 プログラムには、特定の UNIX シグナルを受信するたびにできるだけ早く停止する (そして呼び出し元に戻る) 必要がある関数がいくつかあります。一見すると、シグナルが受信され、呼び出し元関数でのみインターセプトされたときにスローされる例外は、明らかな解決策のように見えます。

void sighandler(int sig) {
   throw new myexc();
}

void caller(void) {
    try {
        callee1();
        callee2();
    } catch (myexc e) {
        ...
    }
}

しかし、安全でポータブルなシグナル処理はかなり制限されています。なぜなら、volatile sig_atomic_t の値を変更することが、シグナル ハンドラーで行うべき唯一の正しいことのように思われるからです。しかし、sig_atomic_t が変更されたかどうかをチェックするテストでコードを散らかしたくありません。

void sighandler(int sig) {
    vol = 1;
}

void callee1(void) {
    do_stuff();
    if (vol == 1) return;
    do_other_stuff();
    if (vol == 1) return;
    do_something_again();
    ...
}

値が変更されるのを待っているスレッドを持ってから、他のスレッドによってキャッチされる例外をスローすることも、有効な解決策ではないようです。

どうすれば安全でポータブルでエレガントな方法でこれを行うことができますか?

4

3 に答える 3

2

シグナルハンドラで例外のスローが許可されていますか? これらは、プログラム フローから完全に独立しています。これも悪い設計です。本当に例外的な状況でのみ例外を使用する必要があります。

さらに、完全な粒度はcallee1必須ですか? ほとんどの場合、関数はコードのいくつかのチャンクでほとんどの時間を費やしているため、戻り条件について多くのチェックを行う必要はありません。

于 2012-06-15T15:34:24.600 に答える
1

できません。一般に、スレッドの迅速な終了を保証する唯一の方法は、そのスレッドを含むプロセスを迅速に終了することです。(Posix では、信号で C 標準よりも少し多くのことが許可されています。たとえば、abort()orを呼び出すことはできますが、 .整合状態にありません。_exit()exit()

于 2012-06-15T16:06:28.590 に答える