2011-10-17 39 views
1

这个问题是跟进的this问题。总之,这是动机 - 从原来的问题的评论有点C/P的:升压ASIO旗语般的解决方案

我希望能够发布关于多线程(CalcFib功能)工作一组,然后将作业时已经结束,另一基团的作业(CalcFib2功能),还对多个线程。这个周期循环多次(这里是二),所以我认为做的最好的事情就是创建boost::asio::io_service,并在循环的开始创建线程,所以我没有创建&销毁线程每次循环开始时间/结束。

我已经创建了两个int乏错误信号_ **命名,并在上面提到的功能递减他们。等待工作组完成的代码如下所示为while。至少在我看来,解决方案是有效的。

是使用while真的很长的路要走等待?我错过了什么?有一个更好的方法吗?

我的代码如下所示:

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

boost::mutex global_stream_lock; 
int semaphore_fib = 0; 
int semaphore_fib2 = 0; 

void WorkerThread(boost::shared_ptr<boost::asio::io_service> io_service) 
{ 
    global_stream_lock.lock(); 
    std::cout << "[" << boost::this_thread::get_id() 
     << "] Thread Start" << std::endl; 
    global_stream_lock.unlock(); 

    io_service->run(); 

    global_stream_lock.lock(); 
    std::cout << "[" << boost::this_thread::get_id() 
     << "] Thread Finish" << std::endl; 
    global_stream_lock.unlock(); 
} 

size_t fib(size_t n) 
{ 
    if (n <= 1) 
    { 
     return n; 
    } 
    boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); 
    return fib(n - 1) + fib(n - 2); 
} 

void CalcFib(size_t n) 
{ 
    global_stream_lock.lock(); 
    std::cout << "[" << boost::this_thread::get_id() 
     << "] Now calculating fib(" << n << ") " << std::endl; 
    global_stream_lock.unlock(); 

    size_t f = fib(n); 

    global_stream_lock.lock(); 
    std::cout << "[" << boost::this_thread::get_id() 
     << "] fib(" << n << ") = " << f << std::endl; 
    semaphore_fib = semaphore_fib-1; 
    global_stream_lock.unlock(); 
} 

void CalcFib2(size_t n) 
{ 
    global_stream_lock.lock(); 
    std::cout << "\t\t[" << boost::this_thread::get_id() 
     << "] Now calculating fib2(" << n << ") " << std::endl; 
    global_stream_lock.unlock(); 

    size_t f = fib(n); 

    global_stream_lock.lock(); 
    std::cout << "\t\t[" << boost::this_thread::get_id() 
     << "] fib2(" << n << ") = " << f << std::endl; 
    semaphore_fib2=semaphore_fib2-1; 
    global_stream_lock.unlock(); 
} 

int main(int argc, char * argv[]) 
{ 
    boost::shared_ptr<boost::asio::io_service> io_service(
     new boost::asio::io_service 
     ); 
    boost::shared_ptr<boost::asio::io_service::work> work(
     new boost::asio::io_service::work(*io_service) 
     ); 
    boost::asio::io_service::strand strand(*io_service); 

    global_stream_lock.lock(); 
    std::cout << "[" << boost::this_thread::get_id() 
     << "] The program will exit when all work has finished." 
     << std::endl; 
    global_stream_lock.unlock(); 

    boost::thread_group worker_threads; 
    for(int x = 0; x < 2; ++x) 
    { 
     worker_threads.create_thread( 
      boost::bind(&WorkerThread, io_service) 
      ); 
    } 
    for(int loop_no=0; loop_no<2; ++loop_no) 
    { 
     semaphore_fib=3; 
     io_service->post(boost::bind(CalcFib, 5)); 
     io_service->post(boost::bind(CalcFib, 4)); 
     io_service->post(boost::bind(CalcFib, 3)); 
     while(semaphore_fib>0) 
     { 
      // waiting 
     } 

     global_stream_lock.lock(); 
     std::cout << "[" << boost::this_thread::get_id() 
      << "] ******* CalcFib group finished ********" << std::endl; 
     global_stream_lock.unlock(); 

     semaphore_fib2=3; 
     io_service->post(boost::bind(CalcFib2, 2)); 
     io_service->post(boost::bind(CalcFib2, 1)); 
     io_service->post(boost::bind(CalcFib2, 1)); 
     while(semaphore_fib2>0) 
     { 
      // waiting 
     } 
     global_stream_lock.lock(); 
     std::cout << "[" << boost::this_thread::get_id() 
      << "] ******* CalcFib2 group finished ********" << std::endl; 
     global_stream_lock.unlock(); 
    } 
    work.reset(); 
    worker_threads.join_all(); 

    return 0; 
} 

回答

0

这是我如何解决太多if声明中while回路main()

  • 添加了boost::condition_variable cv;boost::mutex mx;为全局变量
  • 新增boost::lock_guard<boost::mutex> lk(mx);cv.notify_all();CalcFibCalcFib2功能
  • 新增boost::unique_lock<boost::mutex> lk(mx); cv.wait(lk);while循环

这样,我已经做到了这一点在if声明while只有在执行cv.notify_all()时才执行循环。