标签: kqueue

如何用kevent()替换select()以获得更高的性能?

来自Kqueue维基百科页面:

Kqueue在内核和用户空间之间提供高效的输入和输出事件管道.因此,可以修改事件过滤器以及接收未决事件,同时每个主事件循环迭代仅使用对kevent(2)的单个系统调用.这与较旧的传统轮询系统调用形成对比,例如poll(2)和select(2)效率较低,尤其是在轮询大量文件描述符上的事件时

这听起来很不错.我为我的服务器定位FreeBSD,我正在处理大量的网络套接字fd - 在它们上面使用select()并确定从哪里读取数据.我宁愿使用kevent()调用来获得更高的性能,因为它就是它的用途!

我在这里阅读了关于FreeBSD的kevent手册页,但它对我来说很神秘,而且我找不到解释它的好资源.使用kevent替换select的一个例子可以解决我的问题,也可以帮助我更好地了解如何使用kevent().

c macos performance freebsd kqueue

6
推荐指数
1
解决办法
3158
查看次数

Kqueue常规文件

kqueue(在OS X上)是否对读/写常规文件有用?我知道,epoll的是不是在Linux上常规文件有用的,所以我想知道如果同样是kqueue的事实.

编辑:我不是指读/写文件,显然read()和write()都是为了这个.我的意思是,"kqueue实际上对检测文件何时可读/可写有用吗?"

c sockets macos operating-system kqueue

6
推荐指数
1
解决办法
648
查看次数

使用kqueue响应多个事件类型

当事件注册时,kqueue提供与该事件类型相关的ID; 例如,文件描述符用于标识要监视的文件

int kq;
struct kevent ke;

kq = kqueue();
fd = open(argv[1], O_RDONLY);
EV_SET(&ke, fd, EVFILT_VNODE, EV_ADD, NOTE_DELETE | NOTE_RENAME, 0, NULL);
kevent(kq, &ke, 1, NULL, 0, NULL);

while (1) {
    kevent(kq, NULL, 0, &ke, 1, NULL);
    /* respond to file system event */
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我还需要响应其他事件类型这样的信号,我们需要一个新的kqueue实例,以避免与ident参数的 冲突kevent().

kq_sig = kqueue();
struct kevent ke_sig;

/* set the handler and ignore SIGINT */
signal(SIGINT, SIG_IGN);
EV_SET(&ke_sig, SIGINT, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
kevent(kq_sig, &ke_sig, 1, …
Run Code Online (Sandbox Code Playgroud)

kqueue

6
推荐指数
1
解决办法
1508
查看次数

文件系统事件/ kqueue是否有一个好的objc库包装器来处理递归观察?

我想编写一个OSX(Snow Leopard)应用程序,它可以在特定目录中的文件发生更改时接收通知,并且我希望访问已更改的特定文件的路径.

我知道我可以用做这一点File System Events还是kqueue.前者没有提供更改哪个特定文件的详细信息(要求我构建我正在观看的目录的快照,然后扫描它以找出更改的文件).后者不支持递归观看(要求我以递归方式将监视添加到父目录中的每个文件和目录).

我已经找到了可以为我处理快照/递归乐趣的库,但找不到任何库.UKKQueue对于低级别的kqueue东西看起来像是一个很好的包装器,但似乎没有做递归.同样的GTMFileSystemKQueue.SCEvents看起来像一个很好的包装,File System Events但似乎没有找到更改的特定文件.

是否有一个库可以满足我的要求并且适合这些技术的objc项目?

filesystemwatcher objective-c fsevents kqueue

5
推荐指数
1
解决办法
985
查看次数

fs.watch通过Mac OSX上的Node 0.5.9

我在Node v0.5.9上运行以下命令:

var fs = require("fs");
fs.watch("/Users/username/testingFsWatcher/",function(event,file) {
  console.dir(arguments);
});
Run Code Online (Sandbox Code Playgroud)

然后我做:

  • cd /Users/username/testingFsWatcher/
  • >file1 - > { '0': 'rename', '1': null }
  • mkdir new_folder - > { '0': 'rename', '1': null }
  • >new_folder/file2 - >没有事件触发/输出
  • touch file1 - >没有事件触发/输出
  • rm file1 - > { '0': 'rename', '1': null }

我注意到的两件事似乎不正确:子目录(new_folder)没有被监视,对监视文件的更新/修改不会触发change事件.查看节点代码并测试它们似乎应该是可能的.

那么,是否可以fs.watch观看目录及其所有子目录?是否至少可以从文件修改中获取事件?另外,从我所知道的,fs.watch支持kqueue哪一个eventid(在OSX中),是否有可能得到它eventid

注意:我是专门使用fs.watch而不是fs.watchFile因为我需要观看整个目录(最好是所有的子目录:).

谢谢您的帮助!

kqueue node.js

5
推荐指数
1
解决办法
1635
查看次数

是否有一个 kqueue()/kevent() 相当于 select() 的“errorfds”集?

今天我将一些代码从 select() 移植到 kqueue(),我注意到 kevent() 似乎没有 select() 的“异常设置”功能的模拟。

也就是说,select()的函数签名是:

int select(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict errorfds, struct timeval *restrict timeout);
Run Code Online (Sandbox Code Playgroud)

...对于 kevent(),EVFILT_READ 对应于 (readfds),EVFILT_WRITE 对应于 (writefds),但我没有看到任何像 EVFILT_ERROR 对应于 (errorfds) 的内容。

kevent() 下是否真的不支持套接字错误条件,或者是否存在但以某种对我来说不明显的方式实现?

error-handling select kqueue

5
推荐指数
1
解决办法
273
查看次数

在哪里为 SIGPIPE 声明 sig_t 信号

我目前正在使用 kqueue 来处理服务器进程中每个线程的多个客户端,因此我不希望在出现信号 SIGPIPE 时终止线程,我只想从 kqueue 中删除相应的 socked id。所以我的问题是:有没有办法在 Signalhandle 中获取相应的 socketid 并将其解析回进程以将其从事件 kqueue 中删除,或者我是否只需将 SIG_IGN SIGPIPE 并通过返回 -1 来处理删除发送?它会在超时时间后返回-1值还是立即返回发送-1?

最后,如果信号忽略是我的解决方案: id 必须在哪里放置声明

typedef void (*sig_t) (int);
 sig_t
 signal(int sig, sig_t func);
Run Code Online (Sandbox Code Playgroud)

它必须在 main 函数中吗?或者在相应线程的开头?或者只是作为全局元素?

c sockets signals kqueue

5
推荐指数
1
解决办法
2254
查看次数

kqueue的EV_RECEIPT究竟是什么?

kqueue的机制有一个事件标志,EV_RECEIPT根据链接的手册页,其中:

...对于对kqueue进行批量更改而不会耗尽任何待处理事件非常有用.当作为输入传递时,它强制EV_ERROR始终返回.成功添加过滤器后,数据字段将为零.

然而,我的理解是,在不消耗任何挂起事件的情况下对kqueue进行批量更改是很简单的,只需将nevents参数传递给0 kevent,从而不从队列中抽取任何事件.考虑到这一点,为什么需要EV_RECEIPT

OS X的Apple文档中的一些示例代码实际上使用了EV_RECEIPT:

kq = kqueue();

EV_SET(&changes, gTargetPID, EVFILT_PROC, EV_ADD | EV_RECEIPT, NOTE_EXIT, 0, NULL);
(void) kevent(kq, &changes, 1, &changes, 1, NULL);
Run Code Online (Sandbox Code Playgroud)

但是,看到changeskevent调用之后从未检查过数组,我完全不清楚为什么EV_RECEIPT在这种情况下使用它.

EV_RECEIPT真的有必要吗?它在什么情况下真的有用?

macos freebsd kqueue

5
推荐指数
1
解决办法
313
查看次数

epoll和kqueue之间是否有任何重大的性能差异?

我的开发机器是MacBook(当然有kqueue).但是,在生产中我们正在运行Linux(当然使用epoll).显然,要了解我的代码的性能特征,我需要使用epoll来运行它.那就是说,我在kqueue下看到的表现与epoll看到的相当接近?或者在任何情况下性能可能会有显着差异?在大多数情况下,似乎kqueue和epoll在性能方面非常相似,但我还没有真正做过非常彻底的测试.

如果它有所作为,我在Python中使用龙卷风.

python asynchronous epoll tornado kqueue

4
推荐指数
1
解决办法
1568
查看次数

Kqueue返回EVFILT_READ和EVFILT_WRITE,但我安装了单独的(ident,filt)对

我遇到了一个问题,我不确定是否是来自kqueue的预期行为,或者是否是我做错的事情.

我需要使用kqueue为单个套接字文件描述符安装单独的事件.单独的事件是(sockfd,EVFILT_READ)和(sockfd,EVFILT_WRITE).然而,当我从kqueue中拉出事件后,我从kqueue获得两个事件,但两个事件都包含(event.filter&EVFILT_READ)和(event.filter&EVFILT_WRITE).

我需要将它们分开,否则我不知道哪个事件实际上是准备好的,可读的还是写的?

以下是我用一些示例代码来说明问题.请记住,这只是测试代码,以确定为什么我在每个事件中都得到两个过滤器标志.

int main(int argc, char ** argv) {
    //listening_sockfd = setup listening socket

    //setup kqueue and vars
    int kq = kqueue();
    int res = 0;
    int bufres = 0;
    struct timespec ts = {0};
    struct timespec * tsp = &ts;
    struct kevent ke2[2];

    //install read for listening socket
    struct kevent ke1;
    bzero(&ke1,sizeof(ke1));
    ke1.ident = listening_sockfd;
    ke1.flags = EV_ADD;
    ke1.filter = EVFILT_READ;
    res = kevent(kq,&ke1,1,NULL,0,tsp);

    while(1) {
        new_client:

        //wait for a client to connect
        res = kevent(kq,NULL,0,&ke1,1,NULL);
        if(res …
Run Code Online (Sandbox Code Playgroud)

c kqueue

4
推荐指数
2
解决办法
2204
查看次数