强制触发kevent

发布于 2024-09-11 15:01:29 字数 269 浏览 6 评论 0原文

我在 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 调用返回?

I'm using kqueue for socket synchronization in OS X. I can register an event of interest like the following:

struct kevent change;
EV_SET(&change, connected_socket, EVFILT_READ, EV_ADD, 0, NULL, NULL);
kevent(k_queue_, &change, 1, NULL, 0, NULL);

And the question is, is there a way to trigger this event by force so that the waiting kevent call would return?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

戴着白色围巾的女孩 2024-09-18 15:01:29

除了将数据自然写入套接字的另一端之外,还有一些可能性:)

  • shutdown(2) 该套接字的读取端 - 您将在 中得到 EV_EOF >flags (愚蠢),
  • 使用超时参数并调用相同的处理函数,
  • 使用 自我管道技巧当你需要打破等待时。

但我的问题是:你为什么需要这个?

编辑:

如果我正确理解您的评论,您正在寻找一种方法来解决写入事件的边沿触发行为(EV_CLEAR)。我认为正确的方法是当传出队列中没有任何内容时,从 EVFILT_WRITE 取消注册您的套接字,然后再次重新注册当有数据要发送时。这需要更多的工作,但这就是它的工作原理,并且您不需要任何额外的系统调用,因为 kevent(2) 接受更改和结果。查看 libevent 并了解它如何处理此类东西。你使用的是非阻塞套接字,对吧?

Some possibilities aside from natural writing of data to the other side of the socket :)

  • shutdown(2) the read side of that socket - you'll get EV_EOF in flags (silly),
  • Use the timeout argument and call the same handling function,
  • Use the self-pipe trick when you need to break the wait.

My question though: why do you need this?

Edit:

If I understand your comments correctly you are looking for a way to get around edge-triggered behavior (EV_CLEAR) for write events. I believe that the proper way of doing this is to un-register your socket from EVFILT_WRITE when you don't have anything in the outgoing queue, then re-register it again when there's data to send. It's a bit more work, but that's how it works, and you don't need any additional system calls since kevent(2) accepts both changes and results. Take a look into libevent and see how it handles this sort of stuff. And you are using non-blocking sockets, right?

永言不败 2024-09-18 15:01:29

我会推荐一个稍微不同的解决方案。

将另一个注册事件添加到 kqueue。具体来说是 EVFILT_USER。

您可以使用它来触发您想要唤醒 kevent() 线程的任何行为,而不会导致代码看起来很奇怪或难以维护。

中对其进行了真正的粗略测试

OSX 源代码在http://www.opensource.apple.com/source/xnu/xnu-1699.24.23/tools/tests/xnu_quick_test/kqueue_tests.c

I would recommend a slightly different solution.

Add another registered event to the kqueue. Specifically a EVFILT_USER.

You can use this to trigger whatever behavior you want to wake the kevent() thread up for without the code looking weird or being hard to maintain.

The OSX sources have a real rough test for it in

http://www.opensource.apple.com/source/xnu/xnu-1699.24.23/tools/tests/xnu_quick_test/kqueue_tests.c

清醇 2024-09-18 15:01:29

OSX 10.6 和 FreeBSD 8.1 添加了对 EVFILT_USER 的支持,我们可以使用它从另一个线程唤醒事件循环。

请注意,如果您使用它来实现自己的条件和 timedwait,您仍然需要锁以避免竞争条件,如 这个很好的答案

有关完整代码示例,请参阅我的其他答案: https://stackoverflow.com/a/31174803/432

OSX 10.6 and FreeBSD 8.1 add support for EVFILT_USER, which we can use to wake up the event loop from another thread.

Note that if you use this to implement your own condition and timedwait, you still need locks in order to avoid race conditions, as explained in this excellent answer.

See my other answer for a full code example: https://stackoverflow.com/a/31174803/432

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文