在一个从未调用过也永远不会调用asio::io_context.run()
的线程中,我必须调用post()
或dispatch()
来将任务分配给调用asio::io_context.run()
的线程吗?
在一个从未调用过asio::io_context.run()
的线程中直接调用asio::async_write()
或asio::async_read()
来将任务分配给调用过asio::io_context.run()
的线程是安全的吗?
在一个从未调用过也永远不会调用asio::io_context.run()的线程中,我必须调用post()或dispatch()来将任务分派给调用过asio::io_context.run()的线程吗?
基本上就是这样的。是的,它也是"便宜"的。实现任务队列的方法(参见例如stackoverflow.com/questions/…)对于第一部分:是的。(你可以替换"must"与"can"
在一个线程中直接调用asio::async_write()或asio::async_read()是否安全,而这个线程从来没有调用过asio::io_context.run()来将任务分配给调用过asio::io_context.run()的线程?
可以(有警告)。
需要注意的是你要对线程安全/同步负责。例如,tcp::socket对象不是线程安全的。你应该只从一个逻辑线程(例如,strand)或临界区(例如,使用互斥,互斥)调用它的方法。
异步启动器将工作到执行上下文(.run()
在任意数量的线程上)。从这里开始,所有后续的异步初始化函数都是从完成处理程序中发生的,所以从这些线程中已经发生了。
请注意,这些都不是神奇的。事实上,所有的async_初始化函数都知道executor
(通常与IO对象相关联),这决定了完成处理程序将post
/dispatch
/defer
发送到哪里。在某些情况下,你想要覆盖这个(例如使用strand.wrap()
或更新的bind_executor()
函数)。
参见当你必须传递io_context boost::asio::spawn?(c++)