我可以boost::bind(mycallback, this, _1, _2)
跨C代码使用吗?
更新
简短的回答是否定的,boost bind不会返回一个函数指针,它可以在C代码中调用,但是一个函子(带有重载()
运算符的C++对象)请参见下面的答案.
我真的很困惑 libev 和 libuv。
libuv 只是 POSIX 系统上 libev 的包装器吗?
如果不是,它的区别在哪里?
我正在学习 libev 并且偶然发现了这个问题。假设我想尽快处理某些事情,但不是现在(即不在当前执行函数中)。例如,我想将一些大型同步作业分成多个部分,这些部分将排队,以便其他回调可以在两者之间触发。换句话说,我想用 timeout 安排一个回调0
。
所以第一个想法是ev_timer
与 timeout一起使用0
。第一个问题是:这样有效吗?libev 是否能够将0
超时计时器转换为有效的“尽快调用”工作?我认为不是。
我一直在挖掘libev 的文档,我也发现了其他选项:
它可以通过使用准备或空闲观察者人为地延迟调用回调
所以空闲的观察者在这里可能不会很好,因为
当没有其他相同或更高优先级的事件待处理时,空闲观察者会触发事件
这可能不是我想要的。准备观察者可能会在这里工作。但是为什么不检查观察者呢?我所说的上下文有什么重大区别吗?
这些文档建议的另一个选项是:
或者更偷偷地,通过重用现有的(停止的)观察者并将其推入待处理队列:
ev_set_cb (watcher, callback);
ev_feed_event (EV_A_ watcher, 0);
Run Code Online (Sandbox Code Playgroud)
但这需要始终有一个停止的观察者。此外,由于我事先不知道我想同时安排多少个电话,所以我必须有多个观察者,并另外通过某种列表跟踪它们,并在需要时增加它。
那么我在正确的轨道上吗?这些都是可能性还是我错过了一些简单的东西?
在ev.h
libev 里面,我发现了一些看起来很奇怪但无法理解的宏:
173 # define EV_P struct ev_loop *loop /* a loop as sole parameter in a declaration */
174 # define EV_P_ EV_P, /* a loop as first of multiple parameters */
Run Code Online (Sandbox Code Playgroud)
作者将宏定义EV_P_
为EV_P,
并将其用作函数定义中的第一个参数,如下所示:
int ev_run (EV_P_ int flags EV_CPP (= 0));
Run Code Online (Sandbox Code Playgroud)
好奇为什么不只是写EV_P,
而不是EV_P_
,所以函数参数看起来更清楚用逗号:
int ev_run (EV_P, int flags EV_CPP (= 0));
Run Code Online (Sandbox Code Playgroud)
这是C中的伎俩还是有其他原因?不熟悉C之前的Google,但仍然没有答案.
Libev使用三种数据结构来存储不同的观察者.
堆:对于按时间排序的观察者,例如ev_timer
和ev_periodic
.
链表:如ev_io
,ev_signal
,ev_child
等.
阵列:如ev_prepare
,ev_check
,ev_async
等.
毫无疑问,使用堆来存储计时器观察器.但是选择链表和数组的标准是什么?
存储ev_io观察者的数据结构似乎有点复杂.它首先是一个数组,fd
其索引和数组中的元素是链接列表ev_io watcher
.如果使用链表作为元素,则为数组分配空间更方便.是原因吗?
或者只是因为插入或删除操作ev_io
更频繁而且ev_prepare
看起来更稳定?
还是其他任何原因?
我在 C/Linux 中有一个使用 TCP 套接字的聊天服务器。使用 libev 时,我能够为套接字创建一次读取事件的 ev_io 观察器。就像是:
ev_io* new_watcher = (ev_io*)malloc(sizeof(ev_io));
//initialize the watcher
ev_init(new_watcher, read_cb);
//set the fd and event to fire on write
ev_io_set(new_watcher, watcher->fd, EV_READ);
//start watching
ev_io_start(loop, new_watcher);
Run Code Online (Sandbox Code Playgroud)
这工作正常,因为 read 事件只会在有数据要读取时触发。但是,我必须以不同的方式对待写入事件,因为即使我没有要写入的数据,它们也会不断触发。为了解决这个问题,我让我的 read_callback 为写数据创建一个 ev_io 观察者,只有当有数据准备好被写入时,然后 write_callback 将在发送它的消息后删除观察者。
这意味着每次我需要处理消息时,我都在分配、初始化、设置、监视、取消监视和释放写入监视程序。我担心我可能会错误地和低效地处理这个问题。
在 libev 中处理 write_callback 事件的最佳方法是什么?
提前致谢。
我正在尝试监视一个unix套接字("/ tmp/mysocket").
我可以在Node.js中做到这一点:当1)套接字绑定,2)有人连接到套接字,3)数据被发送到套接字和4)套接字断开时,它引发一个事件.
我现在尝试在C/C++中执行此操作:我想监视"/ tmp/mysocket"以查找上述事件.我看过libevent(我最好喜欢使用),但是看到它需要一个IP:端口.有没有办法监控unix套接字?
或者任何人都可以建议另一个C/C++解决方案?
我在ubuntu上运行gcc编译器我正在使用一个例子来学习如何与libev建立套接字连接我已经安装了libev4和libev-dev但是一切正常,除非我添加struct ev_loop*loop = ev_default_loop(0); 它抛出一个未定义的引用错误任何人都可以告诉我这里有什么问题是我的代码
#include <stdio.h>
#include <netinet/in.h>
#include <ev.h>
#define PORT_NO 3033
#define BUFFER_SIZE 1024
int total_clients = 0; // Total number of connected clients
void accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents);
void read_cb(struct ev_loop *loop, struct ev_io *watcher, int revents);
int main() {
struct ev_loop *loop = ev_default_loop(0); <--error-->
int sd;
struct sockaddr_in addr;
int addr_len = sizeof(addr);
struct ev_io w_accept;
// Create server socket
if ((sd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket …
Run Code Online (Sandbox Code Playgroud) 实际上,我正在使用libev; 但在幕后这是使用epoll(我只在Linux上).当我添加一个观察者来读取文件并且所有数据都已被读取时,我确实得到一个回调,即有数据要读取,但是read(2)返回0(EOF).那时我必须停止观察者,否则它会继续告诉我有东西要读.但是,如果我停止观察者,然后其他一些进程将数据附加到该文件,那么我将永远不会看到它.
获得通知的正确方法是,在我读完之前可以读取的文件中是否有附加/附加数据?
我更喜欢libev方面的答案,但是更低级别也会这样做(我可以将其转化为如何用libev做到这一点).
在新的0.5.1分支中,有一个Node.js的官方Windows可执行文件.Node.js的Linux版本使用已建立的库,例如v8,libev,libeio.
由于libev和libeio适用于*NIX平台; Node.js的Windows端口是否可供生产使用,还是仅用于开发?
我正在使用libebb(http://tinyclouds.org/libebb/)和libev编写一个Web服务器.我正在寻找一个使用libev事件循环的异步httpclient.
我希望它支持Http 1.1(流水线,保持活动等).
我希望这不是一个愚蠢的问题.