2012-05-12 17 views
0

私はブーストスレッドと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(複数のスレッドのための1つのio_service)と一緒にスレッドを処理するのは正しい方法ですか?

スレッドオブジェクトとワーカーオブジェクトはどのように「結合」されていますか?私は彼らが私のようにではないと思う。たとえば、2つのオブジェクトと2つのスレッドをインスタンス化すると、予想される出力が得られます。 2つのオブジェクトと1つのスレッドをインスタンス化すると、プログラムの出力は同じになります。

は(LOGMSGが出力操作を同期させるために、ミューテックスを持つ単純なcoutのラッパーである。)

+0

質問をするときには、情報を保つようにしてください。 – Ankit

+0

コードが正常に見えます。私はおそらく、deadline_timerの代わりにsystem_timerを使用します。 deadline_timerはカレンダー作業を一括して行いますが、system_timerはちょうど "ticks"で動作します – RichardBruce

答えて

0

あなたの例で正しい見えますが、それはこの場合にはASIOを使用する必要があります。スレッドプールの作業キューとしてio_serviceを使用すると、Asio + threadsが最も便利です。そのように使用したい場合は、io_service::postを参照してください。

0

asio::io_serviceはシステムタスクディーラーであり、タスクキューを保持しており、このように使用する必要はありません。io_service::run()を含む独自の関数でスレッドを作成する必要があります。 スレッドとio_serviceは、1対1、または多対1になります。