在事件驱动/异步框架中使用第三方库的回调(无文件描述符)

时间:2010-11-29 19:24:08

标签: c++ events asynchronous

目标是拥有一个单线程事件驱动框架。最终用户将执行以下操作:

class MyEventFramework : public EventFramework {
protected:
  virtual void onData (const Data& data);
  virtual void onReport (const Report& report);
  virtual void onUserRequest (const UserRequest& userRequest);
...
};

幕后还有其他组件,如一系列计时器等。

大多数处理程序都是由我自己的代码调用的,因此我可以在一系列文件中使用select()或类似的概念(kqueue()epoll()等)描述符

我的问题是onData()例程实际上是来自第三方库的回调,我没有源代码。因此,我不能只使用他们的文件描述符;我只知道通过回调发生了一些事情。

现在我有一个多线程的框架实现;在到达用户之前,导致onData()的逻辑出现在单独的线程中。这是不合需要的,因为它需要容易出错的互斥锁,需要昂贵的线程切换(这是一个低延迟的应用程序),以及其他问题。 (为了澄清,由于客户端应用程序中可能存在竞争条件,因此框架中的每个处理程序必须相对于彼此是原子的。)

有没有其他人在此之前遇到过这种情况并过着告诉这个故事?

2 个答案:

答案 0 :(得分:3)

如果我理解正确:您的调度线程在某些系统调用(例如selectpoll)上被阻止,并且您希望onData成员函数遵循相同的通知路径

使用pipe对我来说似乎是一个很好的解决方案而不会过多地损害设计:

  • select监控管道的一端
  • 当调用
  • 时,第3个库回调“响铃”管道的另一端

这允许'线程跳转',唯一的问题是管道应该只用作通知工具:onData函数的参数必须在管道通知和管道通知之间的某处排队处理线程唤醒。

答案 1 :(得分:2)

我偏爱自连接本地UDP套接字(即绑定到INADDR_LOOPBACK,然后连接到同一地址)。此时,您的回调可以写入套接字,可以是单个字节(用于简单唤醒),也可以是带有回调数据的消息。