[英]Is it safe to disable threads on boost::asio in a multi-threaded program?
I read in this SO answer that there are locks around several parts of asio's internals.我在this SO answer中读到,asio内部的几个部分都有锁。
In addition I'm aware that asio is designed to allow multiple threads to service a single io_context
.此外,我知道 asio 旨在允许多个线程为单个
io_context
提供服务。
However, if I only have a single thread servicing a single io_context
, but I want to have more than 1 io_context
in my application, is it safe to disable threads (per BOOST_ASIO_DISABLE_THREADS
)但是,如果我只有一个线程为单个
io_context
提供服务,但我想在我的应用程序中拥有超过 1 个io_context
,那么禁用线程是否安全(每个BOOST_ASIO_DISABLE_THREADS
)
That is: I have one io_context
and one thread which has entered its io_context::run()
loop, and it is servicing a number of sockets etc. All interaction with these sockets are done within the context of that thread.那就是:我有一个
io_context
和一个线程,它进入了它的io_context::run()
循环,它正在为许多套接字等提供服务。与这些套接字的所有交互都是在该线程的上下文中完成的。
I then also have another thread, and another io_context
, and that thread services that io_context
and its sockets etc.然后我还有另一个线程和另一个
io_context
,并且该线程为io_context
及其套接字等提供服务。
Inter-thread communication is achieved using a custom thread-safe queue and an eventfd
wrapped with an asio::posix::stream_descriptor
which is written to by the initiating thread, and read from the receiving thread which then pops items off the thread-safe queue.线程间通信是使用自定义线程安全队列和用
asio::posix::stream_descriptor
包装的eventfd
实现的,由启动线程写入,并从接收线程读取,然后从线程安全弹出项目队列。
So at no point will there be user code which attempts to call asio functions from a thread which isn't associated with the io_context
servicing its asio objects.因此,在任何时候都不会有用户代码尝试从与服务其 asio 对象的
io_context
的线程调用 asio 函数。
With the above use-case in mind, is it safe to disable threads in asio?考虑到上述用例,在 asio 中禁用线程是否安全?
It'll depend.这将取决于。 As far as I know it ought to be fine.
据我所知应该没问题。 See below for caveats/areas of attention.
有关注意事项/注意领域,请参见下文。
Also, you might want to take a step back and think about the objectives.此外,您可能想退后一步考虑目标。 If you're trying to optimize areas containing async IO, there may be quick wins that don't require such drastic measures.
如果您正在尝试优化包含异步 IO 的区域,则可能会有不需要如此激烈措施的快速胜利。 That is not to say that there are certainly situations where I imagine
BOOST_ASIO_DISABLE_THREADS
will help squeeze just that little extra bit of performance out.这并不是说在某些情况下我
BOOST_ASIO_DISABLE_THREADS
将有助于挤出一点额外的性能。
What BOOST_ASIO_DISABLE_THREADS
does is BOOST_ASIO_DISABLE_THREADS
所做的是
boost::asio::detail::thread
throws on construction)boost::asio::detail::thread
在构造时抛出)It's worth noting that system_executor
is the default fallback when querying for associated handler executors.值得注意的是
system_executor
是查询关联的处理程序执行程序时的默认后备。 The library implementation specifies that async initiations will override that default with the executor of any IO object involved (eg the one bound to your socket or timer).库实现指定异步启动将使用任何涉及的 IO 对象(例如绑定到您的套接字或计时器的对象)的执行程序覆盖该默认值。
However, you have to scrutinize your own use and that of third-party code to make sure you don't accidentally rely on fallback.但是,您必须仔细检查自己的使用和第三方代码的使用,以确保您不会意外依赖回退。
Update: turns out system_executor internally spawns a thread_group which uses
detail::thread
- correctly erroring out when used更新:原来 system_executor 在内部产生了一个使用
detail::thread
的 thread_group - 使用时正确出错
Asio is extensible. Asio 是可扩展的。 Some services may elect to run internal threads as an implementation detail.
一些服务可能会选择运行内部线程作为实现细节。
The implementation of this library for a particular platform may make use of one or more internal threads to emulate asynchronicity.
该库针对特定平台的实现可以利用一个或多个内部线程来模拟异步性。 As far as possible, these threads must be invisible to the library user.
这些线程必须尽可能对库用户不可见。 [...]
[...]
I'd trust the library implementation to use detail::thread
- causing a runtime error if that were to be the case.我相信库实现会使用
detail::thread
- 如果是这种情况会导致运行时错误。
However, again, when using third-party code/user services you'll have to make sure that they don't break your assumptions.但是,同样,在使用第三方代码/用户服务时,您必须确保它们不会破坏您的假设。
Also, specific operations will not work without the thread support , like:此外, 如果没有线程支持,特定操作将无法工作,例如:
#define BOOST_ASIO_DISABLE_THREADS
#include <boost/asio.hpp>
#include <iostream>
int main() {
boost::asio::io_context ioc;
boost::asio::ip::tcp::resolver r{ioc};
std::cout << r.resolve("127.0.0.1", "80")->endpoint() << std::endl; // fine
// throws "thread: not supported":
r.async_resolve("127.0.0.1", "80", [](auto...) {});
}
Prints印刷
127.0.0.1:80
terminate called after throwing an instance of 'boost::wrapexcept<boost::system::system_error>'
what(): thread: Operation not supported [system:95]
bash: line 7: 25771 Aborted (core dumped) ./a.out
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.