15

C および C++ 標準は、シグナルの概念をサポートしています。ただし、C11 標準では、関数 signal() をマルチスレッド環境で呼び出すことはできないか、動作が未定義であると規定されています。しかし、シグナルメカニズムはマルチスレッド環境向けのものだと思います。

C11 標準 7.14.1.1.7 からの引用

「マルチスレッド プログラムでこの関数を使用すると、未定義の動作が発生します。実装は、信号関数を呼び出すライブラリ関数がないかのように動作します。」

これについての説明はありますか?

次のコードは自明です。

#include <thread>
#include <csignal>

using namespace std;

void SignalHandler(int)
{
    // Which thread context here?
}

void f()
{
    //
    // Running in another thread context.
    //
    raise(SIGINT); // Is this call safe?
}

int main()
{
    //
    // Register the signal handler in main thread context.
    //
    signal(SIGINT, SignalHandler);

    thread(f).join();
}
4

4 に答える 4

16

しかし、シグナルメカニズムはマルチスレッド環境向けのものだと思います。

この文が中心的な誤解だと思います。スレッド間ではなく、プロセス間通信signal()の方法です。スレッドは共通メモリを共有するため、mutex と制御構造を介して通信できます。プロセスには共通メモリがなく、ファイルシステムなどの明示的な通信構造を使用する必要があります。signal()

于 2013-01-30T21:04:10.240 に答える
4

プロセス固有のシグナリングとスレッド間の通信を混同していると思います。スレッド間で情報を共有している場合は、おそらく新しいC++11 スレッド サポート ライブラリで必要なものが見つかるでしょう。もちろん、それはあなたが本当にやりたいことによります。

私があなたのコードについて言えることから、スレッドが何らかの方法でイベントを「通知」する必要があり、そのイベントが通知されたときにいくつかのコードを実行できるようにしたいと考えています。それを踏まえて、スレッド サポート ライブラリの Futures セクションを詳しく見てみましょう。

于 2013-01-30T21:34:23.023 に答える
2

「マルチスレッド プログラムでこの関数を使用すると、未定義の動作が発生する」という C11 標準のステートメントは、関数 を具体的に参照していますsignal()。したがって、問題は、の使用がsignal()「マルチスレッド プログラムで」行われるかどうかです。

「マルチスレッド プログラム」という用語は、私が知る限り、C 標準では定義されていませんが、複数の実行スレッドが作成され、完了していないプログラムを意味すると考えています。これは、サンプル プログラムで が呼び出された時点signal()でプログラムがマルチスレッド化されていないため、この要件の下でプログラムの動作が未定義ではないことを意味します。

(ただし、C++11 では、「すべてのシグナル ハンドラーに C リンケージが必要です」[18.10 その他のランタイム サポート [support.runtime] p9]が必要です。サンプル プログラムでは C++ リンケージを持つハンドラーを使用しているため、動作は未定義です。)


他の人が指摘しているように、シグナルはスレッド間の通信を目的としていません。たとえば、C および C++ 標準では、実行するスレッドを指定することすらありません。代わりに、標準ライブラリは、ミューテックス、アトミックなど、スレッド間通信用の他のツールを提供します。

于 2013-01-30T21:44:42.167 に答える
1

undefined behaviorという用語を誤解していると思いますが、残念ながら「悪いことが起こる」という意味で過負荷になっています。ここでの用語は、まさにその意味を表しています。C 標準ではsignal、マルチスレッド コンテキストでの使用が何を意味するかについて何の仮定もしていません。

一般に、C 標準のsignal/raiseインターフェイスはそれ自体ではあまり役に立ちませんが、その上に定義されているプラ​​ットフォーム/OS 固有のもののプレースホルダーに過ぎません。

したがって、signalと 脅威の間の相互作用については、契約は得られません。signal別の言い方をすれば、と スレッドの相互作用はプラットフォームの実装に任されています。

于 2016-06-18T10:31:08.900 に答える