8

ある時点で、main()の最初の行までスレッドを安全に作成できないことを読んだことを覚えています。これは、コンパイラが特別なコードを挿入して、静的初期化時に実行されるスレッドを機能させるためです。したがって、構築時にスレッドを作成するグローバルオブジェクトがある場合、プログラムがクラッシュする可能性があります。しかし、今は元の記事を見つけることができず、これがどれほど強い制限であるのか興味があります-それは標準によって厳密に真実ですか?ほとんどのコンパイラに当てはまりますか?それはC++0xでも当てはまりますか?標準に準拠したコンパイラが静的初期化自体をマルチスレッド化することは可能ですか?(たとえば、2つのグローバルオブジェクトが互いに接触していないことを検出し、プログラムの起動を高速化するためにそれらを別々のスレッドで初期化します)

編集:明確にするために、私は少なくとも、実装がこの点で本当に大幅に異なるかどうか、またはそれが疑似標準であるかどうかを感じ取ろうとしています。たとえば、技術的には、この標準では、さまざまなアクセス指定子(public / protected / etc。)に属するメンバーのレイアウトをシャッフルできます。しかし、私が知っているコンパイラは実際にこれを行いません。

4

3 に答える 3

6

あなたが話しているのは、厳密には言語ではなく、C ランタイム ライブラリ (CRT) です。
まず、Windows などのネイティブ コールを使用してスレッドを作成するCreateThread()と、CRT の介入なしで OS に直接送信されるため、好きな場所でスレッドを作成できます。
通常使用できるもう 1 つのオプション_beginthread()は、CRT の一部であるを使用することです。_beginthread()スレッドセーフな errno を持つなど、使用にはいくつかの利点があります。詳細については、こちらをご覧ください。を使用してスレッドを作成する場合_beginthread()、必要な初期化が行われていない可能性があるため、いくつかの問題が発生する_beginthread()可能性があります。

これは、正確に何が前に、どのような順序で起こるかという、より一般的な問題に触れていmain()ます。基本的に、プログラムのエントリ ポイント関数がありmain()、Visual Studio で必要なすべてのことを処理します。CRT にあるこのコードを実際に見て、そこで何が起こっているのかを自分で確認できます。そのコードに到達する最も簡単な方法は、コード内のブレークポイントを停止し、スタック フレームを確認することです。main()

于 2009-09-18T15:23:37.810 に答える
2

根本的な問題は、DllMain でできることとできないことに対する Windows の制限です。特に、DllMain でスレッドを作成することは想定されていません。静的な初期化は、多くの場合、DllMain から発生します。次に、静的初期化中にスレッドを作成できないことは論理的に続きます。

于 2009-09-21T11:36:04.163 に答える
0

C ++ 0x / 1xドラフトを読んでわかる限り、前にスレッドを開始することmain()は問題ありませんが、静的初期化の通常の落とし穴があります。準拠する実装では、静的コンストラクターまたはスレッドコンストラクターが実行する前に、スレッド化を初期化するコードが実行されることを確認する必要があります。

于 2009-09-22T20:50:28.383 に答える