[Boost] ASIO學習筆記:使用strand來serializing thread

posted in: ASIO, boost, C/C++程式設計 | 0
[insert page=’151′ display=’link’],我們知道在多條thread的程式設計中,對於執行的結果我們是無法預期的。雖然使用mutex可以保證thread-safety,但卻無法保證工作能夠照我們所期望的順序執行。

在boost ASIO中提供了strand來解決既能保證thread-safety又能夠讓工作的順序能夠依照post的順序執行。執行並觀察以下的程式結果:

boost::mutex global_stream_lock;
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();
}
void PrintNum( int x ){     
    global_stream_lock.lock();       
    std::cout << "[" << boost::this_thread::get_id() << "] x: " << x << std::endl;
    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 );    
    boost::thread_group worker_threads;      
    for( int x = 0; x < 2; ++x ) {      
        worker_threads.create_thread( boost::bind( &WorkerThread, io_service ) ); 
    }        
    boost::this_thread::sleep( boost::posix_time::milliseconds( 1000 ) );      
    strand.post( boost::bind( &PrintNum, 1 ) );     
    strand.post( boost::bind( &PrintNum, 2 ) );  
    strand.post( boost::bind( &PrintNum, 3 ) );    
    strand.post( boost::bind( &PrintNum, 4 ) );    
    strand.post( boost::bind( &PrintNum, 5 ) ); 
/*    io_service->post( boost::bind( &PrintNum, 1 ) );    
    io_service->post( boost::bind( &PrintNum, 2 ) );     
    io_service->post( boost::bind( &PrintNum, 3 ) );    
    io_service->post( boost::bind( &PrintNum, 4 ) );  
    io_service->post( boost::bind( &PrintNum, 5 ) );*/
    work.reset();      
    worker_threads.join_all();    
    system("pause");
    return 0;
}


可以試著將io_service->post()的註解拿掉並觀察比較二者的結果。

需不需要用到strand的重點在於:function呼叫的順序是否是重要的?

Leave a Reply

Your email address will not be published. Required fields are marked *