我的应用程序在其中监听和处理来自互联网套接字和unix域套接字的消息.现在我需要将SSL添加到互联网套接字,我正在io_service为应用程序中的所有套接字使用单个对象.现在看来我需要io_service为网络套接字和unix域套接字添加单独的对象.我没有在我的应用程序的任何线程,我用async_send和async_recieve和async_accept处理数据和连接.请指出使用io_service具有异步处理程序的多个对象的任何示例.
Tan*_*ury 32
该问题存在一定程度的不确定性,好像io_service需要多个对象一样.我找不到参考文档中的任何内容,或者强制要求单独对象的SSL和UNIX域套接字的概述io_service.无论如何,这里有几个选择:
io_service:尝试使用单个io_service.
如果您没有io_service对象的直接句柄,但是您有一个Boost.Asio I/O对象的句柄,例如套接字,那么io_service可以通过调用获得关联对象的句柄socket.get_io_service().
io_service:如果io_service需要多个对象,则将线程专用于每个对象io_service.此方法用于Boost.Asio的HTTP Server 2示例.
boost::asio::io_service service1;
boost::asio::io_service service2;
boost::thread_group threads;
threads.create_thread(boost::bind(&boost::asio::io_service::run, &service1));
service2.run();
threads.join_all();
Run Code Online (Sandbox Code Playgroud)
这种方法的一个结果是它可能需要由应用程序进行线程安全保证.例如,如果service1和service2两个有调用完成处理message_processor.process(),则message_processor.process()需要或者是线程安全的或称为一个线程安全的方式.
io_service:io_service提供非阻塞替代品run().在io_service::run()所有工作完成之前阻塞的地方 io_service::poll()将运行准备运行并且不会阻塞的处理程序.这允许单个线程在多个io_service对象上执行事件循环:
while (!service1.stopped() &&
!service2.stopped())
{
std::size_t ran = 0;
ran += service1.poll();
ran += service2.poll();
// If no handlers ran, then sleep.
if (0 == ran)
{
boost::this_thread::sleep_for(boost::chrono::seconds(1));
}
}
Run Code Online (Sandbox Code Playgroud)
为了防止在没有可立即运行的处理程序时出现紧凑的循环,可能值得在睡眠中添加.请注意,此睡眠可能会在事件的整体处理中引入延迟.
io_service:一种有趣的方法是使用a strand将完成处理程序转移到单个处理程序io_service.这允许一个线程per io_service,同时防止需要让应用程序进行线程安全保证,因为所有完成处理程序将通过单个服务发布,其事件循环仅由单个线程处理.
boost::asio::io_service service1;
boost::asio::io_service service2;
// strand2 will be used by service2 to post handlers to service1.
boost::asio::strand strand2(service1);
boost::asio::io_service::work work2(service2);
socket.async_read_some(buffer, strand2.wrap(read_some_handler));
boost::thread_group threads;
threads.create_thread(boost::bind(&boost::asio::io_service::run, &service1));
service2.run();
threads.join_all();
Run Code Online (Sandbox Code Playgroud)
这种方法确实会产生一些后果:
io_service进行包装strand::wrap().io_service,创造了额外的复杂性.重要的是要考虑次要io_service不再有工作,导致其run()返回的情况.异步链通常在同一链中发生io_service.因此,该服务永远不会失去工作,因为完成处理程序将在其上发布额外的工作io_service.
| .------------------------------------------.
V V |
read_some_handler() |
{ |
socket.async_read_some(..., read_some_handler) --'
}
Run Code Online (Sandbox Code Playgroud)
另一方面,当使用strand将工作转移到另一个时io_service,在其中调用包装的处理程序service2,使其将完成处理程序发布到其中service1.如果包装的处理程序是唯一的工作service2,则service2不再有工作,导致servce2.run()返回.
service1 service2
====================================================
.----------------- wrapped(read_some_handler)
| .
V .
read_some_handler NO WORK
| .
| .
'----------------> wrapped(read_some_handler)
Run Code Online (Sandbox Code Playgroud)
为了解释这一点,示例代码使用io_service::workfor,service2以便run()在明确告知之前保持阻塞状态stop().
| 归档时间: |
|
| 查看次数: |
13908 次 |
| 最近记录: |