有没有办法将Boost.Asio与Qt4(首选)或GTK主循环集成? GTK像API一样提供poll(2),因此技术上应该是可行的。 Qt提供了自己的网络层,但我更喜欢使用为Boost.Asio编写的现有代码。 我希望使用其他线程将与集成在一起。
是否有任何参考如何为Qt4(首选)或GTKmm?
执行此操作感谢。
修改
我想澄清几件事情,让答案更轻松。 Qt和GTKmm都提供 “选择喜欢”功能:
所以,问题是,如何将现有的“选择器/轮询器”整合为反应器
Boost.Asio io_service
。今天,Boost.Asio可以使用select,kqueue,epoll,/ dev / poll和iocp作为reactor / proactor服务。我想将它集成到GUI框架的主循环中。
欢迎任何建议和解决方案(更好)。
答案 0 :(得分:15)
<强>简单:强>
构建一个QT槽,调用属于gui的io_service::poll_one()
。将该插槽连接到QT的tick
信号。
深度:
幸运的是,Boost.Asio设计得非常好。关于如何为底层异步内部提供执行线程有很多选择。人们已经提到使用io_service::run()
,这是一个有许多缺点的阻止调用。
您只能从单个线程访问gui小部件。外部线程通常需要将事件发布到gui,如果他们想要改变任何小部件。这与Asio的工作方式非常相似。
天真的方法是将一个线程(或计时器)专用于运行io_service::run()
并让Asio完成处理程序发布一个gui信号。 将工作。
相反,您可以使用保证仅在io_service
调用者的执行线程中调用完成处理程序。没有gui线程调用io_service::run()
,因为它阻塞并且可能挂起gui。而是使用io_service::poll()
或io_service::poll_one()
。这将导致从gui线程调用任何挂起的Asio完成处理程序。由于处理程序在gui线程中运行,因此可以自由修改小部件。
现在您需要确保io_service
有机会定期运行。我建议多次重复gui信号调用poll_one()
。我相信QT有一个滴答信号可以解决问题。您当然可以滚动自己的QT信号以获得更多控制权。
答案 1 :(得分:9)
这是一个相当古老的问题,但对于那些正在阅读它的人,我想分享my code,这是一个用于boost :: asio的QAbstractEventDispatcher的实现。
您需要的是在创建QApplication之前添加以下行(通常是在main()中)。
QApplication::setEventDispatcher(new QAsioEventDispatcher(my_io_service));
这将导致io_service与qt应用程序一起在一个线程中运行而没有额外的延迟和性能下降(就像在不时调用io_service :: poll()的解决方案中那样)。
不幸的是,我的解决方案仅适用于posix系统,因为它使用asio :: posix :: stream_descriptor。 Windows支持可能需要完全不同的方法或非常相似 - 我真的不知道。
答案 2 :(得分:6)
如果我正确理解您的问题,您可以为Boost.Asio编写代码。您希望在GUI应用程序中使用该代码。
您的问题中不清楚的是,如果您想通过asynio将Qt / Gtk网络层包装起来,以便您的代码能够正常工作,如果您只是在寻找一个同时具有gui事件循环和asynio的解决方案。 / p>
我将假设第二种情况。
Qt和Gtk都有将方法集成到事件循环中的方法。例如,参见qtgtk,其中Qt事件循环插入到Gtk中。
在Qt的特定情况下,如果要为Qt生成事件,可以使用以下类:QAbstractEventDispatcher。
快速浏览一下boost asio后,我认为你需要做以下事情:
答案 3 :(得分:2)
真正集成主循环 是可能的。这只是一个巨大的痛苦(我还没有真正尝试过)。
在单独的线程上运行io_service :: run()可能就是这样。