libevent - event_base_loop() 是否应该重复获取事件?
libevent - event_base_loop() should it get events repeatly?
这是一个在 linux 上使用 libevent
的简单程序,它跟踪 stdout
fd,当它可写时,回调将打印一些信息到 stdout
。
代码
hello_libevent.c:
// libevent hello
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <event2/event.h>
#include <event2/thread.h>
void event_callback(evutil_socket_t fd, short events, void *arg) {
if(events | EV_WRITE) {
write(fd, "hello\n", 7);
}
sleep(1);
}
int libevent_test() {
int opr;
// enable pthread
if(evthread_use_pthreads() == -1) {
printf("error while evthread_use_pthreads(): %s\n", strerror(errno));
return -1;
}
// create event_base
struct event_base* eb;
if((eb = event_base_new()) == NULL) {
printf("error while event_base_new(): %s\n", strerror(errno));
return -1;
}
// create event
int fd_stdout = fileno(stdout);
struct event* event_stdout;
event_stdout = event_new(eb, fd_stdout, EV_WRITE, &event_callback, NULL);
// add event as pending
struct timeval timeout = {10, 0};
if(event_add(event_stdout, &timeout) == -1) {
printf("error while event_add(): %s\n", strerror(errno));
return -1;
}
// dispatch
if((opr = event_base_loop(eb, EVLOOP_NONBLOCK)) == -1) {
printf("error while event_base_dispatch(): %s\n", strerror(errno));
return -1;
} else if(opr == 1) {
printf("no more events\n");
} else {
printf("exit normally\n");
}
// free event
event_free(event_stdout);
return 0;
}
int main(int argc, char * argv[]) {
return libevent_test();
}
编译:
gcc -Wall hello_libevent.c -levent -levent_pthreads
执行结果:
hello
no more events
问题:
- 在测试中,事件只发生一次,这是预期的行为吗?或者它应该循环获取更多事件直到超时?
- 如何让它连续获取事件?是否有必要在循环中调用
event_base_loop
,而它已经是 loop
?
从 http://www.wangafu.net/~nickm/libevent-book/Ref3_eventloop.html 看来,您可以在循环中调用 event_base_loop
或 event_base_dispatch
。
while (1) {
/* This schedules an exit ten seconds from now. */
event_base_loopexit(base, &ten_sec);``
event_base_dispatch(base);
puts("Tick");
}
事件的主要目的是通知一些繁忙的线程关于其他地方发生的一些事件。所以,这看起来合乎逻辑。
我认为 event.h File Reference 中提到的事件标志 EV_PERSIST
可能会有所帮助。
Persistent event: won't get removed automatically when activated.
When a persistent event with a timeout becomes activated, its timeout is reset to 0.
而不是
//...
event_stdout = event_new(eb, fd_stdout, EV_WRITE, &event_callback, NULL);
//...
您可以将此标志传递给 event_new
//...
event_stdout = event_new(eb, fd_stdout, EV_WRITE|EV_PERSIST, &event_callback, NULL);
//...
其他部分代码保持不变。此时您创建并添加一次事件,无需在循环中调用 event_base_loop。
编译后的程序只会不断打印“hello”行,直到它终止。
顺便说一下,我注意到
write(fd, "hello\n", 7);
进入
write(fd, "hello\n", 6);
消除每行的前导字符'\0'。
这是一个在 linux 上使用 libevent
的简单程序,它跟踪 stdout
fd,当它可写时,回调将打印一些信息到 stdout
。
代码
hello_libevent.c:
// libevent hello
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <event2/event.h>
#include <event2/thread.h>
void event_callback(evutil_socket_t fd, short events, void *arg) {
if(events | EV_WRITE) {
write(fd, "hello\n", 7);
}
sleep(1);
}
int libevent_test() {
int opr;
// enable pthread
if(evthread_use_pthreads() == -1) {
printf("error while evthread_use_pthreads(): %s\n", strerror(errno));
return -1;
}
// create event_base
struct event_base* eb;
if((eb = event_base_new()) == NULL) {
printf("error while event_base_new(): %s\n", strerror(errno));
return -1;
}
// create event
int fd_stdout = fileno(stdout);
struct event* event_stdout;
event_stdout = event_new(eb, fd_stdout, EV_WRITE, &event_callback, NULL);
// add event as pending
struct timeval timeout = {10, 0};
if(event_add(event_stdout, &timeout) == -1) {
printf("error while event_add(): %s\n", strerror(errno));
return -1;
}
// dispatch
if((opr = event_base_loop(eb, EVLOOP_NONBLOCK)) == -1) {
printf("error while event_base_dispatch(): %s\n", strerror(errno));
return -1;
} else if(opr == 1) {
printf("no more events\n");
} else {
printf("exit normally\n");
}
// free event
event_free(event_stdout);
return 0;
}
int main(int argc, char * argv[]) {
return libevent_test();
}
编译:
gcc -Wall hello_libevent.c -levent -levent_pthreads
执行结果:
hello
no more events
问题:
- 在测试中,事件只发生一次,这是预期的行为吗?或者它应该循环获取更多事件直到超时?
- 如何让它连续获取事件?是否有必要在循环中调用
event_base_loop
,而它已经是loop
?
从 http://www.wangafu.net/~nickm/libevent-book/Ref3_eventloop.html 看来,您可以在循环中调用 event_base_loop
或 event_base_dispatch
。
while (1) {
/* This schedules an exit ten seconds from now. */
event_base_loopexit(base, &ten_sec);``
event_base_dispatch(base);
puts("Tick");
}
事件的主要目的是通知一些繁忙的线程关于其他地方发生的一些事件。所以,这看起来合乎逻辑。
我认为 event.h File Reference 中提到的事件标志 EV_PERSIST
可能会有所帮助。
Persistent event: won't get removed automatically when activated.
When a persistent event with a timeout becomes activated, its timeout is reset to 0.
而不是
//...
event_stdout = event_new(eb, fd_stdout, EV_WRITE, &event_callback, NULL);
//...
您可以将此标志传递给 event_new
//...
event_stdout = event_new(eb, fd_stdout, EV_WRITE|EV_PERSIST, &event_callback, NULL);
//...
其他部分代码保持不变。此时您创建并添加一次事件,无需在循环中调用 event_base_loop。 编译后的程序只会不断打印“hello”行,直到它终止。
顺便说一下,我注意到
write(fd, "hello\n", 7);
进入
write(fd, "hello\n", 6);
消除每行的前导字符'\0'。