3

我很难理解,如何将 kqueue 用于用户空间事件。
我寻找 2 个用例。
用例 1:手动复位事件
用例 2:自动复位事件

我想我明白了,如何使用 kqueue() 和 kevent(),但我不清楚传递给 kevent() 的事件如何查找相关操作:
假设有一个名为“event”的 struct kevent 变量。
让我们假设,我们可以毫无问题地找到一个新的事件 id,它不会与该 kqueue 实例的其他事件 id 发生冲突,名为“eventId”。

  1. 创建用户事件:EV_SET(&event, eventId, EVFILT_USER, EV_ADD, NOTE_FFNOP, 0, NULL)
  2. 销毁用户事件:EV_SET(&event, eventId, EVFILT_USER, EV_DESTROY, NOTE_FFNOP, 0, NULL)
  3. 设置用户事件:EV_SET(&event, eventId, EVFILT_USER, ?????, NOTE_FFNOP, 0, NULL)
  4. 重置用户事件:EV_SET(&event, eventId, EVFILT_USER, ??EV_CLEAR???, NOTE_FFNOP, 0, NULL )
  5. 脉冲用户事件:EV_SET(&event, eventId, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL )
  6. 在等待循环中,我认为剪断会随之而来: if( event.filter == EVFILT_USER && event.ident == eventId ) { // 这是我的事件!做一点事!}

看到了???在上面的 EV_SET() 调用中查看我需要帮助的地方。
对于用例 1(手动重置事件),操作 (1) 创建与用例 2(自动重置事件)相比可能看起来不同。
操作 (3) 和 (4) 我完全一无所知。我可能需要 EV_ENABLE/EV_DISABLE 吗?EV_CLEAR 适合哪里?
到目前为止,我假设除了“调度”之外,我不需要在操作 (6) 中做任何事情。我很肯定,操作(5)可以按照我上面给出的那样工作。

我现在花了一天的时间试图找到说明它是如何完成的文档或示例。我在苹果代码库中找到了一个 kqueue 测试程序,但我怀疑它是否正确。此外,它仅在测试中发送 1 个事件,并且该事件终止接收线程的循环。所以这并不能帮助我理解我的 2 个用例的细节。

我计划在 x86 机器上的 FreeBsd 9.1 下使用它……暂时。

4

1 回答 1

6

经过一番实验,我发现:

  1. 创建用户事件:EV_SET(&ev, identifier, EVFILT_USER, EV_ADD, NOTE_FFCOPY, 0, NULL)
  2. 销毁用户事件:EV_SET(&ev, identifier, EVFILT_USER, EV_DELETE, 0, 0, 0)
  3. 设置用户事件:EV_SET(&event, m_eventId, EVFILT_USER, EV_ENABLE, NOTE_FFCOPY|NOTE_TRIGGER|0x1, 0, NULL)
  4. 重置用户事件:EV_SET(&event, m_eventId, EVFILT_USER, EV_DISABLE, EV_CLEAR|NOTE_FFCOPY, 0, NULL)
  5. 脉冲用户事件:未测试...暂时使用用例 1。
  6. 等待代码片段:如原始帖子中所述。

测试就像一个魅力。在我的测试中,我做了 NOTE_FFCOPY 的事情,但我认为没有必要。

用户事件有 2 种状态 - 已发出信号,未发出信号。EV_ENABLE 和 EV_DISABLE 似乎设置了这些状态。

测试验证,信号状态的事件实际上是由 kevent() 重复报告的。

于 2013-04-18T10:18:20.590 回答