3

次のコードの精度に興味がありました

for(int i=0 ; i<5 ; i++)
{
SomeClass* ptrinst = new SomeClass()
boost::thread t(  boost::bind (&SomeClass::SomeMethod,ptrinst));
......
}

t がスコープ外になると、実行中のスレッドはどうなりますか?

4

1 に答える 1

2

メイン スレッドは を呼び出さないため、t.join()メイン スレッドは引き続きループを実行し、追加のスレッドを生成してから先に進みます。したがって、答えは、現在のコーディングでは、子スレッドは親スレッドと対話しない (少なくとも直接ではない) ということです。

threadまた、クラスは奇妙な獣であることに注意してください。スコープから外れると、メインスレッドに呼び出すハンドルがなくなるだけt.join()です。親スレッドの範囲外にあるという事実は、子スレッドにはまったく影響しません。子スレッドをインスタンス化して生成すると、子は基本的に親から切り離されます (親で表示されていたグローバル/動的に割り当てられたメモリも子に表示されますが、必要に応じてミューテックスが必要になります)これらのグローバルを変更/変更します)。この投稿の後半で述べたように、スレッド化コンテキスト内でのメモリの可視性と所有権についてしっかりと理解する必要があります。ここで私のコメントを読んだだけでは、おそらく役に立たないでしょう。

メインスレッドが子スレッドの完了を待機するようにするには、それらのスレッドをstd::vector<boost::thread> v;ループの外側に格納してから、2 番目のループでjoinそれらすべてのインスタンスを呼び出す必要があります。

bind を介してインスタンス メソッドを呼び出しているため、現在のコードは少し疑わしいように見えます。これは問題ありませんが、通常はそのインスタンス メソッドが呼び出さdelete this;れるとは思わないため、親スレッドがクリーンアップする必要があります (親スレッドはそうすべきではありません)。子スレッドが完了するまでクリーンアップします)。ただし、ある種のスレッド同期がなければ、適切なタイミングでクリーンアップする方法はありません。したがって、メモリ リークやある種の厄介な競合状態がほぼ確実に発生します (クリーンアップを試みるためにメイン スレッドdelete ptrinst;...一部に a を配置するとします。何らかの同期がなければ、子スレッドの前にポインターを削除する可能性があります)。使用済みです)。

また、ブースト バージョンの代わりにstd::threadandを使用することもできます。std::bind

最後に 1 つ注意してください: スレッドの使用をまだ試していると思われます。これが本当なら、このコードを修正しようとするまで、もっと単純な例を読んで実験することをお勧めします。さもなければ、あなたは自分自身を傷つける世界に設定しているかもしれません (競合状態、奇妙なメモリ同期の問題などを含む地獄のデバッグ...)。

メモリとスレッドで何が起こるか、つまり、どのメモリがどのスレッドから見えるか、どのメモリが共有できるか、共有できないかについて、より確実な理解を構築するようにしてください。

于 2013-06-16T08:54:47.917 に答える