答えて
号
シグナル・ハンドラはそうthread_local
が有効な意味を持っていない、彼らは上で実行しているどのスレッドの概念を持っていません。 【intro.multithread] P2:
raise
関数への呼び出しの結果として実行されるシグナルハンドラはraise
関数への呼び出しとして実行の同じスレッドに属します。それ以外の場合は、どのスレッドに信号ハンドラ呼び出しが含まれているかは不明です。また
関連P23である:彼らは異なるスレッドによって実行される、または
- 場合
つのアクションは、潜在的に同時ですシグナルハンドラによって実行されます。
プログラムの実行は、シグナルハンドラのための特別な場合を除き、それはアトミックではない少なくとも1つのうち2つの潜在的に同時矛盾する行動を、含まれている場合データレースを含まず、どちらも他の前に起こります以下で説明します。そのようなデータ競合は、未定義の動作をもたらす。
(シグナルハンドラのための特別な場合のみタイプvolatile sig_atomic_t
に関するていると呼ばれている、ここでは適用されない。)
第二弾が原因[intro.execution] P6の関係:
raise
関数の呼び出しの結果としてシグナルハンドラが実行された場合、ハンドラの実行はraise
関数が呼び出された後で復帰する前にシーケンス化されます。 [注:信号が別の理由で受信されると、シグナルハンドラの実行は、通常、プログラムの残りの部分と並んでいません。 - エンドノート]
この回答はildjarnによって与えられた答えに補遺考えることができます。 C++ 14標準について厳密に言えば、信号ハンドラからのthread_localストレージでデータを使用すると、未定義の動作が発生します。
ただし、特定のプラットフォームでは、このような使用が許可されている可能性があります。たとえば、ほとんどのPOSIXシステムでは、スレッドごとに(スタックのように)割り当てられた特別なデータセグメントを使用してスレッドローカルストレージを実装しています。詳細な説明については、this documentを参照してください。この場合、スレッドローカルデータへのアクセスはロックを伴わないため、非同期信号安全です。
ただし、アトミックがアクセスされていないか、またはアクセスがstd::atomic_signal_fence
を使用してフェンス化されていない限り、シグナルハンドラによって読み取られたり書き込まれたデータは、矛盾する可能性があります。この理由は、シグナルハンドラが実行を中断し、読み書き命令を並べ替える可能性があるときにコンパイラが考えているからです。 std::atomic_signal_fence
は、この並べ替えを禁止し、CPUによる並べ替えは同じスレッド内で実行され、結果(スレッド内の)が命令が順番に実行された場合と同じである場合にのみ命令の並べ替えを許可されるため、 。
std :: atomic_signal_fenceに加えて、std :: atomic型の変数はロックされていない限り安全です(std :: is_lock_freeで示される)。
Linuxでは(と私はほとんどのPOSIXプラットフォームを信じています)、シグナルが特定のスレッドにディスパッチされるかどうかは、このシグナルの生成方法とシグナルの正確なタイプによって決まります。たとえば、SIGSEGV
とSIGBUS
は、エラーの原因となったスレッドに常に送出されます。この場合、スレッドローカルストレージを使用することは、そのようなエラーから回復するための便利な方法です。しかし、C++標準をサポートするすべてのプラットフォームにコードを移植可能にしながら、これを行う方法はありません。
- 1. 定義、初期化、および使用方法 - ベクトル<ベクトル<ペア< int,int >、int>> v C++では?
- 2. カスタムコンパレータ<int型、ペア<int, int>>
- 3. これは同等ですか? <br></p> <pre><code>mergesort(int * arr, int low, int high){ if(low==high){ return; } //mergesort(); //mergesort(); //merge(); } </code></pre> <p>は、私はいつでも低等しくなると信じて:<code>merge sort</code>と<code>quicksort</code>の主な機能で
- 4. メモリ効率の良いマップ<pair <int,int>、set <int>>代替
- 5. 非静的データメンバ 'linkedlist <int> :: dummyNode'の無効な使用C++
- 6. ベクトル<int> v(istream_iterator <int>(cin)、istream_iterator <int>());
- 7. for(int i = 0; i <10; ++ i)とfor(int i = 0; i <10; i ++)は同じものを返しますか?
- 8. マルチセットでの下限の検索<pair <int,int>>(C++)
- 9. テンプレートmake_unique <int[]>初期化子
- 10. ベクトル<pair <int、pair <int,int> >> Pythonのデータ構造
- 11. intを0に初期化するかどうかを指定します。私は、彼らがJavaでは</p> <pre><code>protected int mPaddingRight = 0; protected int mPaddingLeft = 0; protected int mPaddingTop; protected int mPaddingBottom; </code></pre> <p>として4つの変数を定義する参照アンドロイドのソースコードで
- 12. C#の同等::ベクトル<int> .END()
- 13. C++。なぜstd :: cout << char + int int値を出力しますか?
- 14. C++演算子<<(char)ですが、出力はヘキサ/ int
- 15. <Int> == <String>
- 16. リターンするC#Linqクエリ<int,int[]>
- 17. unorderable types:str()<int()
- 18. ベクトル<pair <aStruct *、int>>は不可能ですか?
- 19. 「マージ(のstd ::ベクトル<int>&、のstd ::ベクトル<int>&)
- 20. エラー:非集約型 'ベクトル<int>'はイニシャライザリストで初期化できません
- 21. unorderered_set <tuple <int,int>>の方法は?
- 22. 明示的なキャストは存在しますが、Dictionary <int、string []>をIDictionary <int、IEnumerable <string>>
- 23. "multiset <int、greater <int>> ms1"と "multiset <int> ms2(より大きい<int>()の違いは何ですか?"
- 24. 'System.Collections.Generic.Dictionary <int型、System.Collections.Generic.Dictionary <string,int>> .Dictionary(int型)' の最良のオーバーロードされたメソッドの試合
- 25. 建設中の初期化?私は<code>a(c), b(a)</code>として<code>a</code>で<code>b</code>の初期化についてはよく分からない、今</p> <pre><code>struct A{ int a; int b; A(int c): a(c), b(a){ } }; int main() { A b(10); } </code></pre> <p>:
- 26. 私は機能</p> <pre><code>void make_zero(int matrix[][],int row,int col) { int row, col; int i,j; for(i=0;i<row;i++) { for(j=0;j<col;j++) { if(matrix[i][j]==0){ printf("%d %d\n", i, j); } } } </code></pre> <p>を使用してみました
- 27. KotlinのJava static finalフィールドと同等のものは何ですか? Kotlinで同等である何</p> <pre><code>class Hello { public static final int MAX_LEN = 20; } </code></pre> <p>:Javaでは
- 28. argv []をintとしてどのように取得できますか?私はこれを行う</p> <pre><code>int main (int argc, char *argv[]) { printf("%d\t",(int)argv[1]); printf("%s\t",(int)argv[1]); } </code></pre> <p>とシェルで:
- 29. タスク<T>対して非同期の代理人はC#でですか?
- 30. 「同じシグネチャ」のテンプレートと非テンプレート関数のオーバーロードが非テンプレート関数を呼び出すのはなぜですか?</p> <pre><code>template< class T = const int & > void f(T) {} void f(const int &) {} int main() { f(0); } </code></pre> <p>は、なぜそれが二番目の代わりに、最初の呼び出しん:
シグナルハンドラは[\ [support.runtime \]/10](http://eel.is/c++draft/support.runtime#10)によって制約されます。 –