0

Linux でマルチスレッド C++ ブーストを行っています。

ロックを使用しようとしても、次のプログラムにはまだ競合状態があります。

結果は 8 または 9 または 5 です。それは起こらないはずです。

 #include <iostream>
 #include <boost/bind.hpp>
 #include <boost/threadpool.hpp>
 #include <boost/thread/mutex.hpp>
 #include <boost/thread.hpp>

 boost::mutex myMutex ;
 int g = 0 ;

 void f()
 {

    //myMutex.lock();
    {
            boost::mutex::scoped_lock lock(myMutex);
            ++g;
    }
    //myMutex.unlock();
    return ;
 }
 const int threadnum = 10;
 int main()
 {
    boost::threadpool::fifo_pool tp(threadnum);
    for (int i = 0 ; i < threadnum ; ++i)
            tp.schedule(boost::bind(f));
    std::cout << g << std::endl ;
    return 0 ;
 }

どんな助けでも大歓迎です。

ありがとう !

4

3 に答える 3

7

http://threadpool.sourceforge.net/tutorial/intro.htmlから:

タスクは実行のみがスケジュールされていることを理解することは非常に重要です。スケジュールはすぐに返され、タスクがいつ実行されるか、および処理にかかる時間についての保証はありません。

10 個のタスクをスケジュールし、ラインに到達するまでに実行された数の結果をすぐに印刷します。

std::cout << g << std::endl ;

したがって、ミューテックスはスレッドが一度に 1 つずつ g をインクリメントするようにしますが、結果を出力する前にスレッドが終了するのを待っているわけではありません。コードを変更する 1 つの方法は、プール内のすべてのタスクが終了するまで待機することです。

boost::threadpool::fifo_pool tp(threadnum);
for (int i = 0 ; i < threadnum ; ++i)
        tp.schedule(boost::bind(f));
tp.wait(); //WAIT FOR TASKS TO EXECUTE
std::cout << g << std::endl ;
return 0 ;
于 2012-06-08T21:08:23.880 に答える
5

これを正しく読んでいるかどうかはわかりませんが、g をインクリメントする一連のことをスケジュールしてから、g の内容に対して cout を呼び出しているようです。ミューテックスは、スケジュールされた proc が互いに踏みにじられるのを防ぎますが、最後に cout がすべて完了するまで待機することを強制するものは何もありません。そのためには、ある種の読み取り/書き込みミューテックスが必要です。

于 2012-06-08T20:57:30.570 に答える
0

子スレッドが終了する前にメイン スレッドが終了しているように見えます。これが、一見ランダムな g の値を取得する理由です。子が終了するまでメインスレッドを待機させる方法はたくさんあります。

タスクがスレッドプールで完了するのを待ちます

于 2012-06-08T21:03:12.373 に答える