2012-05-12 2 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 (여러 스레드에 대해 하나의 io_service)와 함께 사용하는 것이 올바른 방법입니까?

스레드 개체와 "작업자"개체는 서로 어떻게 "묶인"상태입니까? 나는 그들이 내가 그랬던 것처럼 생각하지 않는다. 예를 들어, 두 개의 객체와 두 개의 스레드를 인스턴스화하면 예상되는 결과가 나옵니다. 두 객체와 하나의 스레드를 인스턴스화하면 프로그램의 출력은 같습니다.

+0

질문 할 때 유익한 정보를 제공하십시오. – Ankit

+0

코드가 정상적으로 보입니다. 아마도 deadline_timer 대신 system_timer를 사용할 것입니다. deadline_timer는 많은 작업을 수행합니다. 반면 system_timer는 "틱"으로 작동합니다. – RichardBruce

답변

0

내 예 제대로 표시합니다 (logMsg이. 출력 동작을 동기화하는 뮤텍스 간단한 COUT 래퍼)하지만,이 경우 ASIO 입력을 사용할 필요가있다. 스레드 풀의 작업 대기열로 io_service을 사용하면 Asio + threads가 가장 유용합니다. 그런 식으로 사용하려면 io_service::post을 살펴보십시오.

0

asio::io_service은 시스템 작업 딜러 일 뿐이며 작업 대기열을 처리하고 이와 같이 처리 할 필요가 없습니다. io_service::run()을 포함하는 고유 한 기능으로 스레드를 만들어야합니다. 스레드와 io_service은 일대일 또는 다 대일 일 수 있습니다.