每一天至少有一个观察者失败
libev more then one watcher per fd fails
我似乎不能得到工作2个观察者每个插座。下面的代码实际上根本不起作用,但是如果我混淆了这些调用(例如,为一个观察者调用init/set/start,然后为其他观察者调用),我只得到一个观察者工作。我是不是错过了什么?我不认为这与循环和设置有任何关系……我有1个接受循环(默认循环)和1个循环接受连接。我尝试了这两种方法,在接受连接后直接运行下面的代码,然后通过ev_async_send(…),然后从其他io循环执行此代码。结果是一样的。另外,在一个监视器上设置两个事件也可以。
谢谢
ev_init (pSockWatcher->_wW, &CNetServer::send_cb);
ev_init (pSockWatcher->_wR, &CNetServer::recv_cb);
ev_io_set (pSockWatcher->_wW, pSockWatcher->_sd, EV_WRITE );
ev_io_set (pSockWatcher->_wR, pSockWatcher->_sd, EV_READ );
ev_io_start (loop, pSockWatcher->_wR);
ev_io_start (loop, pSockWatcher->_wW);
嗯,这里有一个在一个套接字fd上有两个I/O监视器的例子,这对我来说似乎工作得很好。我正在使用ev_io_init()函数,但是,不是ev_init()和ev_set()。
#include <ev.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
static struct ev_loop *loop;
static ev_timer timeout_watcher;
static ev_io in_watcher, out_watcher;
static ev_idle idle_watcher;
static int sock_fd;
// socket input watcher
static void in_cb(EV_P_ ev_io *watcher, int revents) {
int r, t;
char buf[1024];
for (t = 0; (r = read(sock_fd, buf, sizeof(buf))) > 0;) {
t += r;
write(STDOUT_FILENO, buf, r); // copy input to stdout
if (buf[r-1] == 'n') break; // operate line-at-a-time
}
fprintf(stderr, "in: count = %dn", t);
if (r == 0) {
fputs("in: connection closedn", stderr);
ev_io_stop(loop, &in_watcher); // stop the socket watcher
ev_break(loop, EVBREAK_ALL); // exit the loop
} else if (r < 0) {
perror("read");
}
}
// socket output watcher
static void out_cb(EV_P_ ev_io *watcher, int revents) {
int r, t, lim;
char buf[1024];
ev_io_stop(loop, &out_watcher);
for (t = 0; t < sizeof(buf); t++) {
buf[t] = 'a' + (rand() % 26);
}
for (t = 0, lim = rand() % 10000 + 1000;
(r = write(sock_fd, buf, (lim - t > sizeof(buf)) ? sizeof(buf) : lim - t)) > 0;) {
t += r;
if (t >= lim) break;
}
if (r < 0) {
perror("write");
}
fprintf(stderr, "out: finished sending, count = %dn", t);
}
static void timeout_cb(EV_P_ ev_timer *watcher, int revents) {
fprintf(stderr, "timeout: now = %fn", ev_now(loop));
// send a bunch of stuff on the socket when able
ev_io_start (loop, &out_watcher);
}
static void idle_cb(EV_P_ ev_idle *watcher, int revents) {
static long idle_count = 0;
fprintf(stderr, "idle: count = %ldn", ++idle_count);
sleep(1); // simulate doing stuff
}
int main() {
extern int errno;
int master_fd;
int sock_opt = 1;
int conn_port = 7000;
struct sockaddr_in addr;
socklen_t addrlen;
// **** the following is needed to set up a socket to receive data ****
master_fd = socket(AF_INET, SOCK_STREAM, 0);
if (master_fd == -1) {
perror("socket");
return errno;
}
if (setsockopt(master_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &sock_opt, sizeof(sock_opt)) == -1) {
perror("setsockopt");
return errno;
}
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(conn_port);
addrlen = sizeof(addr);
if (bind(master_fd, (struct sockaddr *) &addr, addrlen) != 0) {
perror("bind");
return errno;
}
if (listen(master_fd, 3) != 0) {
perror("listen");
return errno;
}
fprintf(stderr, "awaiting a connection on port %dn", conn_port);
sock_fd = accept(master_fd, (struct sockaddr *) &addr, &addrlen);
if (sock_fd == -1) {
perror("accept");
return errno;
}
fputs("in: connection establishedn", stderr);
// **** end of socket setup code ****
// define a loop
loop = ev_default_loop(0);
// define a repeating timer
ev_timer_init (&timeout_watcher, timeout_cb, 5.0, 5.0);
ev_timer_start (loop, &timeout_watcher);
// define an idle process
ev_idle_init(&idle_watcher, idle_cb);
ev_idle_start (loop, &idle_watcher);
// define the socket data receiver
ev_io_init(&in_watcher, in_cb, sock_fd, EV_READ);
ev_io_start (loop, &in_watcher);
// define the socket data write complete watcher
ev_io_init(&out_watcher, out_cb, sock_fd, EV_WRITE);
// run the loop
ev_run(loop, 0);
// clean up
close(sock_fd);
close(master_fd);
return 0;
}
相关文章:
- 如何设计具有不同类型的通知和观察器的观察者模式?
- 反射 + 函数指针与观察者模式
- 观察者模式不起作用
- 观察者带有共同指针
- 观察者模式:为什么主题应该是抽象的?
- 使用 RxCpp 构建观察者/可观察模式
- C 设计:多个TCP客户端,Boost ASIO和观察者
- 使用POCO的多深度目录观察者
- 观察者模式专业化
- C 样本观察者模板类误差
- 如何在不必绑定到特定类的情况下实现观察者模式
- C++,函数指针与观察者模式
- 列表<观察者*>*和列表<观察者*>C++的区别
- Intotify观察者在LS或观看命令后停止工作
- 观察者常量正确性
- C++11观察者模式(信号、插槽、事件、更改广播器/侦听器,或任何您想称之为的东西)
- 修复 C++ 中的观察者设计模式
- 实施观察者模式C
- C++自己的观察者模式
- 每一天至少有一个观察者失败