用户在libevent中触发了事件

时间:2011-10-04 08:35:14

标签: libevent

我目前正在使用libevent编写一个多线程应用程序。

某些事件是由IO触发的,但我需要使用event_active()在代码本身的线程中触发一些事件。

我曾尝试编写一个简单的程序来显示我的问题所在:

使用event_new()创建事件,并将fd设置为-1。

调用event_add()时,如果使用了超时结构,则event_base_dispatch将在以后正确处理该事件。

如果使用event_add(ev,NULL),则返回0(显然成功),但event_base_dispatch()返回1(这意味着没有正确注册事件。)

可以使用以下代码测试此行为并交换event_add行:

#include <event2/event.h>
#include <unistd.h>

void cb_func (evutil_socket_t fd, short flags, void * _param) {
  puts("Callback function called!");
}

void run_base_with_ticks(struct event_base *base)
{
  struct timeval one_sec;

  one_sec.tv_sec = 1;
  one_sec.tv_usec = 0;
  struct event * ev1;
  ev1 = event_new(base, -1, EV_PERSIST, cb_func, NULL);
  //int result = event_add(ev1, NULL);
  int result = event_add(ev1, &one_sec);
  printf("event_add result: %d\n",result);

  while (1) {
     result = event_base_dispatch(base);
     if (result == 1) {
       printf("Failed: event considered as not pending dispite successful event_add\n");
       sleep(1);
     } else {
       puts("Tick");
     }
  }
}

int main () {
  struct event_base *base = event_base_new();
  run_base_with_ticks(base);
  return 0;
}

编译:g ++ sample.cc -levent

问题是,我不需要超时,也不想使用n年超时作为解决方法。因此,如果这不是使用用户触发事件的正确方法,我想知道它是如何完成的。

1 个答案:

答案 0 :(得分:8)

你的方法很健全。在Libevent 2.0中,您可以使用event_active()来激活另一个线程中的事件。只需确保事先使用evthread_use_windows_threads()或evthread_use_pthreads(),告诉Libevent使用正确的线程库。

至于需要额外的事件:在Libevent 2.0及更早版本中,当没有添加待处理事件时,事件循环将立即退出。你最好的选择可能是你发现的超时技巧。

如果您不喜欢,可以使用内部“event_base_add_virtual”函数告诉event_base它有虚拟事件。但是,此功能不会导出,因此您必须说出以下内容:

    void event_base_add_virtual(struct event_base *);
    // ...
    base = event_base_new();
    event_base_add_virtual(base); // keep it from exiting

但这有点像黑客攻击,并且它使用了一个未记录的函数,所以你需要注意以防万一它不能用于更高版本的Libevent。

最后,这个方法现在对你没有帮助,但有一个未来版本的Libevent(2.1及更高版本)有一个补丁,可以向event_base_loop()添加一个新标志,以防止它在循环超出事件时退出。补丁是over on Github;它主要是等待代码审查,以及更好的选项名称。