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 ;

因此,虽然您的互斥锁确保线程一次增加一个 g,但您无需等待它们完成后再打印结果。修改代码的一种方法是等待池中的所有任务完成:

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。您的互斥锁可防止预定的 procs 相互践踏,但没有什么能迫使 cout 最后等到它们全部完成。为此,您需要某种读/写互斥锁。

于 2012-06-08T20:57:30.570 回答
0

似乎主线程在孩子之前完成 - 这就是为什么你会得到看似随机的 g 值。有很多方法可以让主线程等到子线程完成,即

等待线程池中的任务完成

于 2012-06-08T21:03:12.373 回答