在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