根据我的理解,学习boost asio并找到一个叫“strand”的类.
如果只有一个io_service与一个特定的链相关联,并且将该句柄放在一起.
如果只有一个io_service与一个特定的链相关联,并且将该句柄放在一起.
示例(从here)
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 ) );
那么这个线将会为我们的序列化处理程序执行.但是这样做的好处是什么?为什么我们不要创建一个线程(例如:在for循环中make x = 1),如果我们希望任务变成序列化的?
解决方法
想想一个系统,其中单个io_service管理数百个网络连接的套接字.为了能够并行化工作负载,系统维护一个调用io_service :: run的工作线程池.
现在这种系统中的大部分操作都可以并行运行.但有些则必须序列化.例如,您可能不希望同一套接字上的多个写入操作同时发生.然后,您将使用一个套接字来同步写入:在不同的套接字上写入可能会同时发生,同时对同一套接字的写入将被序列化.工作线程不必关心同步或不同的套接字,只需抓取任何io_service :: run手它们.
有人可能会问:为什么我们不能只使用互斥体来进行同步?线的优点是,如果线已经在工作,工作线程将不会首先被安排.使用互斥体,工作线程将获得回调,然后阻止锁定尝试,从而防止线程在互斥体可用之前进行任何有用的工作.