具有多个线程的Boost条件变量

时间:2014-03-15 13:21:25

标签: c++ multithreading boost

在我的程序中,我有两个基本线程。第一个是主线程,第二个是Tcp服务器线程。 TCP服务器将监听请求,并且对于每个请求,它将创建相应的线程,每个新创建的线程应该开始工作,直到它们到达某个点,他们必须等待来自主线程的指示。为了解决这个问题,我使用Boost 1.49实现了一个条件变量。

我的主要问题是,当任何新创建的线程到达条件变量的点时,我的整个程序就会冻结。

有关详细信息,请查看: Boost 1.49 Condition Variable issue

到目前为止,我没有得到任何积极的回应,我无法解决问题。

非常感谢。

1 个答案:

答案 0 :(得分:1)

我没有看过你的其他问题(代码太多)

通常,您必须等待/发出相应互斥锁下的条件信号。

这是一个演示,使用一组等待启动信号的10名工人:

  • 查看 Live On Coliru

    #include <boost/thread.hpp>
    #include <boost/optional/optional_io.hpp>
    
    /////////////////////////
    // start condition logic
    
    boost::mutex mx;
    boost::condition_variable cv;
    
    static bool ok_to_start = false; 
    
    void await_start_condition()
    {
        boost::unique_lock<boost::mutex> lk(mx);
        cv.wait(lk, [] { return ok_to_start; });
    }
    
    void signal_start_condition()
    {
        boost::lock_guard<boost::mutex> lk(mx); 
        ok_to_start = true;
        cv.notify_all();
    }
    
    /////////////////////////
    // workers
    static boost::optional<int> shared_secret;
    
    void worker(int id)
    {
        await_start_condition();
    
        // demo worker implementation
        static boost::mutex console_mx;
        boost::lock_guard<boost::mutex> lk(console_mx);
        std::cout << "worker " << id << ": secret is " << shared_secret << "\n";
    }
    
    int main()
    {
        boost::thread_group threads;
    
        for (int i = 0; i<10; i++)
            threads.create_thread(boost::bind(worker, i));
    
        // demo - initialize some state before thread start
        shared_secret = 42;
    
        // signal threads can start
        signal_start_condition();
    
        // wait for all threads to finish
        threads.join_all();
    }
    
  • 对于C ++ 03,您可以用手写的谓词替换lambda: Live On Coliru

    namespace /* anon detail */
    {
        bool ok_to_start_predicate() { return ok_to_start; }
    }
    
    void await_start_condition()
    {
        boost::unique_lock<boost::mutex> lk(mx);
        cv.wait(lk, ok_to_start_predicate);
    }
    
  • 或者您可以使用Boost Lambda / Boost Phoenix为您解决问题: Live On Coliru

    #include <boost/phoenix.hpp>
    void await_start_condition()
    {
        boost::unique_lock<boost::mutex> lk(mx);
        cv.wait(lk, boost::phoenix::cref(ok_to_start));
    }