在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