一个io_service对象可以通过多个线程调用io_service.run进行事件处理器的并发。分发到不同的线程上执行的策略可以认为是随机的。
strand是线程安全的任务队列的封装,具体执行还是会调用io_service的接口进行处理。一个io_service可以被多个strand绑定。
因此strand的特性是保证同一个strand里面的任务是按序执行,任务执行的线程是根据io_server.run线程分配的,所以一个strand里面的任务执行的线程并不一定是同一个。
下面是strand.post具体实现:
void strand_service::do_post(implementation_type& impl,
operation* op, bool is_continuation)
impl->mutex_.lock();
if (impl->locked_)
// Some other handler already holds the strand lock. Enqueue for later.
impl->waiting_queue_.push(op);
impl->mutex_.unlock();
// The handler is acquiring the strand lock and so is responsible for
// scheduling the strand.
impl->locked_ = true;
impl->mutex_.unlock();
impl->ready_queue_.push(op);
io_service_.post_immediate_completion(impl, is_continuation);
}
使用例子:
int main(int argc, char* argv[])
io_service io;
io_service::work worker(io);
for (int i = 0; i < 3; i++)
std::thread t([&](){io.run(); });
t.detach();
boost::asio::strand str1(io);
// step 1
for (int i = 0; i < 10; i++)
io.post([=]()
cout << i << endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
cout << "AAAAAAAAAAAAAAAAAAAAA" << endl;
// step 2
for (int i = 0; i < 10; i++)
str1.post([=]()
cout << i << " tid:" << std::this_thread::get_id() << endl;
::system("pause");
return 0;
}
输出:
使用例子中的step1是直接使用io_service进行任务分发,因此执行顺序是乱序的。
使用例子中的step2是通过strand封装进行任务分发,因此是顺序执行,执行的线程也不一定是同一个。