问题标签 [kqueue]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - epoll、kqueue、用户指定指针:如何在多线程环境中安全地释放它?
我们可以在 Unices 系统中用于异步 I/O 警报的工具,例如 Linux 上的 epoll、BSD 系统上的 kqueue 和 Solaris /dev/poll 或 I/O 端口,所有这些都允许用户指定一个与用户想要接收 I/O 警报的文件描述符。
通常在这个指针中,用户指定一个指向一个结构的指针,该结构将抽象一个文件描述符(例如“Stream”结构,或类似的东西),并且每次打开一个新的文件描述符时,用户都会分配一个新的结构。
例如struct stream { int fd; int flags; callback_t on_read_fn; /* ... */ };
现在,我的问题是:如何安全地释放用户在多线程环境中分配的这个结构?
我问这个,因为 epoll/kqueue/etc 的性质:你通常有一个线程从内核“下载”一个事件向量,包含具有一些 I/O 准备的文件描述符,以及一个与之关联的用户指针文件描述符。
现在,让我们考虑一下我有 2 个线程:T1 下载这些事件并处理它们,例如调用stream->on_read_fn();
等,T2 简单地运行用户代码、用户事件和类似的东西。
如果 T2 想要关闭一个文件描述符,只需执行此操作close(stream->fd);
,T1 就不会再收到该 fd 的任何 I/O 警报,因此在stream
那里释放结构是安全的。
但是,如果 T1 线程已经在它正在处理的事件向量中下载了相同的文件描述符,但它还没有处理那个文件描述符呢?
如果 T1 被安排在 T2 之前,它会没问题,但如果 T2 被安排在 T1 之前,它将关闭文件描述符并释放stream
结构,因此线程 T1 在处理该文件描述符时将有一个用户关联指针,指向一个已经释放的结构!当然,这会严重崩溃。
我的观点是,如果线程 T1 为该特定文件描述符下载了一些 I/O 警报,T2永远不会知道,T2 也无法预测 T1 是否会下载一些 I/O 警报或根本不下载!
这非常棘手,它让我头晕目眩。有什么想法吗?在这种情况下,何时可以安全地释放用户指定的指针?
注意:我的一个朋友建议在调用之前从 epoll/kqueue 队列中删除文件描述符close(2)
。没错,这就是我现在所做的,但这并不能解决问题,因为 T2 可以从 epoll/kqueue 队列中删除文件描述符,但这并不能保证该文件的 I/O 事件描述符尚未从内核“下载”,将很快由线程 T1 处理。
c - Kqueue udata 字段更改
在我使用 kqueue 的 mac 上,它声明 udata 未更改。event_data
然而,调用中返回的数组kevent
正在被修改。什么可能导致这种情况?我正在传递指向转换为 void* 的字符串的指针,当我kevent
在前 3 个字符之后读取时,其余的都被修改了。
谢谢
c - 修改目录中的文件时不会触发目录上的 kqueue
我使用 kquque 来监控桌面:
flags
-EV_ADD | EV_CLEAR
fflags
-NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_LINK | NOTE_RENAME | NOTE_REVOKE
filter
-EVFILT_VNODE
但是,当我.js
使用 sublime2 软件在桌面上编辑文件时,它不会触发通知:(
请指教
这是我的 js-ctypes 代码:
c - kqueue 监视目录大小的变化
我正在尝试使用 kqueue 观察目录的大小变化,这可能吗?这样做的原因是因为我正在监视目录,并且每当触发事件时,我都会统计目录并比较上次修改时间等,以确定是否发生了内容修改、添加、删除或重命名事件。我的目标是在目录内的文件上发生内容修改时在目录上触发,我无法做到这一点,所以我们有一个想法,我们想要检测目录上的大小变化,就好像内容修改发生在一个文件上,那么目录的大小将会改变。这可能吗?
谢谢
macos - 是否可以使用 `select()` 轮询 kqueue 的文件描述符?
当你创建一个 kqueue 时,kqueue()
你会得到一个文件描述符。但似乎无法使用select()
. 我知道从 a 轮询/读取的标准kqueue()
方法是 withkevent(...)
但我正在尝试与一些使用select()
.
这里的目标是能够触发可以通过这种select
基于轮询机制检测到的“用户事件”(即使该事件最终需要在kevent()
以后使用“消费”)。这看起来像是EVFILT_USER
天生要做的事情,但是一个快速的实验表明,select()
当在 kqueue 中添加(和触发)事件时,不会报告 kqueue 的 fd 已准备好读取,它只是超时(或阻塞永远)。(但等效的kevent()
调用确实看到/返回事件。)
难道我做错了什么?还是不能用 来轮询 kqueue 的 fd select()
?
macos - kevent & USB serial ports
I'm having trouble using kevent on mac with a USB serial console. I've narrowed it down to:
When I run this and unplug the USB device in the middle of the call to kevent(), I get:
My understanding is that the contents of the event translates to:
FD 4, EVFILT_READ, EV_ADD, 6 bytes remaining on fd. But the ioctl() fails (since the device was removed), and errno is also 6, so it seems as if event.data is returning the errno, not the bytes remaining.
How can I differentiate between the normal read case and the case where the device has been removed? The filter, flags & fflags appear the same in both cases.
Additional Information
If I switch from opening the serial console to a pipe, and write a single byte followed by closing the write end, I get:
This is what I expect, since 0x8000 is EV_EOF.
macos - 如何使用 Kqueue 检测文件何时被发送到垃圾箱?
我在 mac os x 上使用 Kqueues,我正在尝试监视一个文件夹,所以我使用了 EVFILT_VNODE 过滤器,我想在删除文件时收到通知,我试过NOTE_DELETE
但它只检测文件何时被删除unlink() system call
但不是当我将文件移动到垃圾箱时。
问题是如何检测文件何时被发送到垃圾箱?
python - 调用 kevent 函数时文件没有错误
我在 Python 2.7 中使用 kqueue 来构建文件监视器。
最初,它在 flags 中不断输出 0x4000,在 data 中输出 0x1,结果是发生了错误。然后我找到了LaclefYoshi给出的一个例子,它有效!
我的代码,给出错误。
他的版本,将文件对象直接交给 kevent 函数。
另一个版本,在 kevent 中调用一个 fileno 方法。
但是现在我真的很困惑为什么第一个版本不起作用而第三个版本很好。这两个应该是一样的吧?
我的另一个问题是,Python 中的文件对象到底是什么?我在这里看到ident实际上是一个整数,应该是文件描述符而不是文件对象。怎么在这里工作!?
谢谢!
macos - 为什么 poll 表明一个 kqueue 观察一个空的 Mach 端口集是可读的?
我有一个 kqueue 正在监视一个项目:一个空的 Mach 端口集。kevent64
表示没有可用的事件,并select
表示 kqueue 尚未准备好读取。但是poll
说 kqueue是可读的!kevent64
- 尽管在随后调用以读取假定准备好的事件时,情况似乎并非如此。
我正在使用的代码如下。你可以用类似的东西来构建它gcc -Wall -std=c99 -o test test.c
,然后用它./test
或其他东西运行它。它打印出以下返回值kevent64
:(在尝试读取 1 而无需等待后实际检索到的事件计数)、select
(轮询后准备读取的文件描述符计数)和poll
(轮询后准备读取的文件描述符计数)。
我期望的输出是这样的,表明kevent64
,select
并且poll
所有人都同意 kqueue 是空的。
但我实际上得到的是这个,显示kevent64
并select
说一件事,poll
另一件事 - 而且,即使在poll
表明 kqueue 是可读的之后,kevent64
仍然说没有要读取的事件(这是第二次kevent64
调用的原因)。
revents
( is的 1 值POLLIN
,据说,表示可以在没有阻塞的情况下读取数据。如果我单独指定POLLRDNORM
,结果是相同的POLLRDBAND
。)
为什么会出现差异?
我的测试代码:
c++ - epoll 或 kqueue 是否可以处理向自身异步添加文件描述符
如果一个线程(比如 X)正在等待epoll_wait()
另一个线程(比如 Y)调用epoll_ctl()
以注册对文件描述符的兴趣9
。之前在线程 X 中的调用能否epoll_wait()
返回线程 Y 添加的文件描述符9
?初始调用epoll_wait()
在任何时候都不会在中间返回。
现在我想对此进行比较,并就操作系统中的另外两个轮询调用提出相关问题。poll()
和kqueue
- 如果上述问题的答案是正确的,那么有没有办法通过
poll()
系统调用实现类似的行为? - 让我们假设它
epoll_ctl()
是线程安全的,线程 X 可以安全地调用epoll_ctl()
并通过调用epoll_wait()
返回文件描述符9
是否准备好进行 I/O。声明对文件描述符感兴趣的函数和等待函数的分离是使这个函数令人惊叹的原因。但是人们经常将kqueue
andepoll
称为用于相同的功能。但是kqueue
,没有单独的函数来声明对获取描述符的事件反馈感兴趣。有谁知道如何kqueue
以类似的方式使用epoll
?epoll
如果它允许线程安全“利益声明”,它似乎是目前最好的线程安全选项