2012-05-12 259 views
0

我正在學習Boost線程和Asio(異步輸入/輸出),並且我寫了下面的示例將一些概念放在一起。提升線程和提升Asio

class Worker { 
    private: 
    boost::asio::io_service&  m_ios; 
    boost::asio::deadline_timer m_timer; 
    unsigned      m_cycles; 
    unsigned      m_time2wait; 
    std::string     m_threadName; 

    public: 
    Worker(boost::asio::io_service& ios, 
      unsigned cycles, unsigned time2wait, const std::string& name); 
    ~Worker(); 
    void start(); 
    void run(); 
    void stop(); 
}; 


Worker::Worker (boost::asio::io_service& ios, 
       unsigned cycles, unsigned time2wait, const std::string& name) 
: m_ios(ios), 
    m_timer(ios, boost::posix_time::seconds (1)), 
    m_cycles(cycles), 
    m_time2wait(time2wait), 
    m_threadName(name) 
{ 
    logMsg(m_threadName, "is starting . . . "); 
} 

Worker::~Worker() 
{ 
    logMsg(m_threadName, "is ending . . . "); 
} 

void Worker::start() 
{ 
    logMsg (m_threadName, "start was called"); 

    m_timer.expires_at (m_timer.expires_at() + 
       boost::posix_time::seconds (m_time2wait)); 
    m_timer.async_wait (boost::bind (&Worker::run, this)); 
} 

void Worker::stop() 
{ 
} 

void Worker::run() 
{ 
    if (m_cycles > 0) 
    { 
    logMsg (m_threadName, "run # ", m_cycles); 
    --m_cycles; 
    m_timer.expires_at (m_timer.expires_at() + 
         boost::posix_time::seconds(m_time2wait)); 
    m_timer.async_wait(boost::bind(&Worker::run, this)); 
    } 
    else { 
    logMsg (m_threadName, "end of cycling"); 
    } 
} 

void run_threads (boost::asio::io_service& io_srv) 
{ 
    Worker worker_1(io_srv, 5, 2, "worker 1"); 
    Worker worker_2(io_srv, 5, 4, "worker 2"); 
    worker_1.start(); 
    worker_2.start(); 

    boost::shared_ptr <boost::thread> worker_Thread_One (
    new boost::thread (boost::bind (&boost::asio::io_service::run, &io_srv))); 

    boost::shared_ptr <boost::thread> worker_Thread_Two (
    new boost::thread(boost::bind(&boost::asio::io_service::run, &io_srv))); 

    worker_Thread_One->join(); 
    worker_Thread_Two->join(); 
} 

int main (int argc, char** argv) 
{ 
    boost::asio::io_service ios; 

    run_threads(ios); 

    return 0; 
} 

我試圖讓一些線程並行工作,每個線程通過一個特定的對象來完成它的工作。這個例子顯然似乎工作,但我覺得我錯了混合線程和Asio(壞設計)。是否有線程與Asio一起工作的正確方法(一個用於多線程的io_service)?

線程對象和「worker」對象如何「綁定」在一起?我認爲他們不是我所願。例如,如果我實例化兩個對象和兩個線程,我有預期的輸出。如果我實例化了兩個對象和一個線程,則程序的輸出是相同的。

(該logMsg是一個簡單的COUT包裝用互斥同步的輸出操作)。

+0

當你問一個問題時,儘量保持信息。 – Ankit

+0

代碼看起來很理智。我可能會使用system_timer而不是deadline_timer。 deadline_timer會做一堆日曆工作,而system_timer只是在「ticks」中工作 – RichardBruce

回答

0

你的例子看起來是正確的,但它沒有必要在這種情況下都使用ASIO。當您使用io_service作爲線程池的工作隊列時,Asio +線程最爲有用。如果你想以這種方式使用它,請調查io_service::post

0

asio::io_service只是一個系統任務的經銷商,它擁有一個任務隊列並對其進行處理,你不需要像這樣使用它,你應該創建一個包含你自己功能的線程,其中包括io_service::run()。 線程和io_service可以是一對一或多對一的。