为什么Boost.Asio的不支持基于事件的接​​口(例如,沿条件变量信令的东西线)? [英] Why does Boost.Asio not support an Event-based interface (for example, something along the lines of condition variable signaling)?

查看:220
本文介绍了为什么Boost.Asio的不支持基于事件的接​​口(例如,沿条件变量信令的东西线)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解Boost.Asio的,即使可能实现使用条件变量与Boost.Asio的结合信号系统的意向。

I am attempting to understand Boost.Asio, with the intention of potentially implementing a signaling system using condition variables in conjunction with Boost.Asio.

我见过的其他StackOverflow的问题,<一个href=\"http://stackoverflow.com/questions/6775873/boost-asio-asynchronously-waiting-on-a-condition-variable\">boost ASIO异步等待一个条件变量,提高:: ASIO异步状态和<一个HREF =htt​​p://stackoverflow.com/questions/6644631/boost-condition-variable-issue>升压条件变量问题,但没有对这些问题/答案已经圆满地触及了一个重要的问题,我有这是真的,和/或有一个根本原因,Boost.Asio的是不适用的,天然的契合,条件变量

I have seen the other StackOverflow questions boost asio asynchronously waiting on a condition variable, boost::asio async condition, and boost condition variable issue, but none of these questions/answers have satisfactorily touched on an essential question that I have: Is it true that, and/or is there a fundamental reason why, Boost.Asio is not applicable to, or a natural fit with, condition variables?

我的想法是,条件变量是使用操作系统级同步对象内部实现(例如,提高::螺纹:: condition_variable在Windows上使用Windows操作系统的信号)。因为,以我目前的理解,提高:: ASIO :: io_service对象是用于封装操作系统级同步对象,条件变量会因此似乎是天作之合。

My thinking is that condition variables are internally implemented using operating-system level synchronization objects (for example, boost::thread::condition_variable on Windows uses a Windows OS semaphore). Because, to my current understanding, boost::asio::io_service is intended to encapsulate OS-level synchronization objects, condition variables would therefore seem to be a natural fit.

这是事实,不同的文件操作和插座操作上,通常就是绝不会在操作系统回调函数的有信号的条件相关联的水平的(我想 - 我我不知道这个)。然而,似乎很简单,只需要求用户提供回调函数,当一个条件变量信号被调用来执行内Boost.Asio的这样一个回调处理程序 - 就像用户必须提供其它一个完成处理程序提高:: ASIO :: io_service对象服务。

It is true that unlike file operations and socket operations, there is typically never a callback function at the operating system level associated with a signaled condition (I think - I am not sure about this). However, it would seem simple enough to implement such a callback handler within Boost.Asio by simply requiring the user to provide a callback function that is to be called when a condition variable is signaled - just as users must provide a completion handler routine for other boost::asio::io_service services.

例如(这只是一个快速的思想,而不是一个完整的原型 - 它不包含足够的参数来处理notify_one()与notify_all(),并不表示服务是如何知道何时退出,并有可能还有其他明显的疏漏或缺陷):

For example (this is just a quick thought, not a complete prototype - it does not include sufficient parameters to deal with notify_one() vs. notify_all(), doesn't indicate how the service knows when to exit, and likely has other glaring omissions or flaws):

void condition_handler_function() {}
boost::asio::io_service service;
boost::mutex mut;
boost::condition_variable cond;

// The following class is **made up by me** - would such a class be a good idea?
boost::asio::io_service::condition_service
             condserv(service, cond, mut, condition_handler_function); 

condserv.async_wait_on_signal();

service.run(); // when condition variable is signaled by notify_one(),
               // 'handler_function()' would be called


// ... in some other thread, later:
cond.notify_one(); // This would trigger 'handler_function()'
                   // in this theoretical code

也许,如果我试图填补了code段上面提到的失落的细节,它会成为我清楚,这可能不是一个干净的方式工作。然而,这种努力是不平凡的。

Perhaps, if I tried to fill in the missing details noted above the code snippet, it would become clear to me that this could not work in a clean way. However, this effort is non-trivial.

所以,我想在这里发布问题。是否有一个很好的理由的条件变量不被支持Boost.Asio的?

Therefore, I would like to post the question here. Is there a good reason why condition variables are not supported by Boost.Asio?

附录

我已经改变了文章的标题引用基于事件的接​​口,因为丹拿的回答,下面,澄清,我认为这是一个真正的基于事件的接​​口,我问(不是真的条件变量)

I have changed the title of the post to reference "Event-based interface", since Tanner's answer, below, has clarified to me that it is really an Event-based interface that I am asking about (not really condition variables).

推荐答案

Boost.Asio的是一个C ++库实现网络和低级别的I / O编程。这样,操作系统级同步对象,如条件变量,是库的范围之外,并且​​一个更好的适合Boost.Thread。在笔者Boost.Asio的往往presents在的boost ::支持ASIO :: io_service对象为应用程序和操作系统之间的桥梁或链接。虽然这可能是过度简化,它是在OS的I / O服务的范围内。

Boost.Asio is a C++ library for network and low-level I/O programming. As such, OS-level synchronization objects, such as condition variables, are outside of the scope of the library, and a much better fit for Boost.Thread. The Boost.Asio author often presents the boost::asio::io_service as the bridge or link between the application and the OS. While this may be an over simplification, it is within the context of the OS's I/O services.

异步编程已经有一种与生俱来的复杂性由于操作开始到完成的时间间隔和空间。 <一href=\"http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/overview/core/strands.html\">Strands提供了一个相当干净的解决方案,提供处理程序的严格顺序调用,而不需要明确的锁定。由于锁定是隐式的,线程安全,应用code可以使用无股的死锁的恐惧。在另一方面,有的boost ::支持ASIO :: io_service对象:: condition_service 外部提供的对象上执行隐同步可能会变成一个复杂的库成一个复杂的。它可能不是很清楚,应用程序开发人员有什么互斥量上的处理程序同步,互斥的状态。此外,它引入了应用程序更容易死锁的事件处理循环的能力,由于隐含的锁定。

Asynchronous programming already has an innate complexity due to the separation in time and space between operation initiation and completion. Strands provided a fairly clean solution to provide strict sequential invocation of handlers, without the need of explicit locking. As the locking is both implicit and thread-safe, application code can use strands without the fear of deadlocking. On the other hand, having boost::asio::io_service::condition_service perform implicit synchronization on an externally provided object may turn a complex library into a complicated one. It may not be clear to the application developer what mutex on which the handler was synchronized, and the state of the mutex. Additionally, it introduces the ability for applications to more easily deadlock the event processing loop due to the implicit locking.

如果基于事件的处理程序调用需要发生的,再一个相当简单的方法是使用相同的方法Boost.Asio的的的timeout服务器例子使用:<一href=\"http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/reference/deadline_timer.html\"><$c$c>boost::asio::deadline_timer. A的 deadline_timer 到期时间可设置为 ::了posix_time pos_infin ,引起<一个href=\"http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/reference/basic_deadline_timer/async_wait.html\"><$c$c>async_wait's处理程序只一旦定时器已取消调用

If event-based handler invocation needs to occur, then one fairly simple alternative is use the same approach Boost.Asio's timeout server example uses: boost::asio::deadline_timer. A deadline_timer's expiry time can be set to posix_time::pos_infin, causing an async_wait's handler to only be invoked once the timer has been canceled:


  • <$c$c>cancel()可以作为notify_all(),,所有优秀的处理器排队等待调用运行。

  • <$c$c>cancel_one()可以作为notify_one(),其中一个突出处理的最大排队等候调用运行。

有一个简单的例子,忽略错误code处理,如下:

A simple example, ignoring error code handling, is as follows:

#include <iostream>

#include <boost/asio.hpp>
#include <boost/thread.hpp>

class event
{
public:
  explicit
  event(boost::asio::io_service& io_service) 
    : timer_(io_service)
  {
    // Setting expiration to infinity will cause handlers to
    // wait on the timer until cancelled.
    timer_.expires_at(boost::posix_time::pos_infin);
  }

  template <typename WaitHandler>
  void async_wait(WaitHandler handler)
  {
    // bind is used to adapt the user provided handler to the deadline 
    // timer's wait handler type requirement.
    timer_.async_wait(boost::bind(handler));
  }

  void notify_one() { timer_.cancel_one(); }
  void notify_all() { timer_.cancel();     }

private:
  boost::asio::deadline_timer timer_;
};

void on_event() { std::cout << "on_event" << std::endl; }

int main()
{
  boost::asio::io_service io_service;
  event event(io_service);

  // Add work to service.
  event.async_wait(&on_event);

  // Run io_service.
  boost::thread thread(boost::bind(&boost::asio::io_service::run,
                       &io_service));

  // Trigger event, causing the on_event handler to run.
  event.notify_one();

  thread.join();  
}

这篇关于为什么Boost.Asio的不支持基于事件的接​​口(例如,沿条件变量信令的东西线)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆