我在OS X中使用kqueue进行套接字同步。我可以注册一个感兴趣的事件,如下所示:
struct kevent change;
EV_SET(&change, connected_socket, EVFILT_READ, EV_ADD, 0, NULL, NULL);
kevent(k_queue_, &change, 1, NULL, 0, NULL);
问题是,有没有一种方法可以强制触发这个事件,以便等待的kevent调用返回?
发布于 2010-07-29 00:08:09
除了将数据自然地写入到套接字的另一端之外,还有一些可能性:)
shutdown(2)
套接字的读取端-您将在flags
中获得EV_EOF
(愚蠢),我的问题是:你为什么需要这个?
编辑:
如果我正确理解了您的评论,您正在寻找一种方法来绕过写事件的边缘触发行为(EV_CLEAR
)。我相信这样做的正确方法是在传出队列中没有任何内容时从EVFILT_WRITE
注销套接字,然后在有数据要发送时重新注册套接字。这需要更多的工作,但这就是它的工作方式,并且您不需要任何额外的系统调用,因为kevent(2)
同时接受更改和结果。看看libevent
,看看它是如何处理这类事情的。而且您使用的是非阻塞套接字,对吧?
发布于 2012-03-05 04:42:40
我会推荐一个稍微不同的解决方案。
将另一个注册的事件添加到kqueue。特别是EVFILT_USER。
您可以使用它来触发您想要唤醒kevent()线程的任何行为,而不会使代码看起来很奇怪或难以维护。
OSX源代码对它进行了非常粗糙的测试
http://www.opensource.apple.com/source/xnu/xnu-1699.24.23/tools/tests/xnu_quick_test/kqueue_tests.c
发布于 2015-07-02 15:40:16
OSX10.6和FreeBSD 8.1添加了对EVFILT_USER
的支持,我们可以使用它从另一个线程唤醒事件循环。
请注意,如果您使用它来实现您自己的条件并计时,那么您仍然需要锁来避免竞争条件等待,如this excellent answer中所述。
有关完整的代码示例,请参阅我的另一个答案:https://stackoverflow.com/a/31174803/432
https://stackoverflow.com/questions/3354733
复制相似问题