kqueue的EV_RECEIPT具体是用来做什么的?

6
kqueue机制中有一个事件标志,EV_RECEIPT,根据链接的man页面所述:

...对于在不排空任何挂起事件的情况下批量更改kqueue非常有用。作为输入传递时,它强制始终返回EV_ERROR。当成功添加过滤器时,数据字段将为零。

然而,我的理解是通过将nevents参数设置为0并从队列中不抽取任何事件,可以轻松地对kqueue进行批量更改而不排空任何挂起事件。那么,为什么需要EV_RECEIPT
苹果OS X文档中的示例代码实际上使用了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);

但是,既然changes数组在kevent调用后从未被检查,我完全不清楚为什么在这种情况下使用EV_RECEIPT

EV_RECEIPT是否真的必要?在什么情况下它才会真正有用?

1个回答

4
如果您正在进行批量更改,其中一个更改导致错误,则事件将在 eventlist 中放置,并在 flags 中设置 EV_ERROR,在 data 中包含系统错误信息。因此,可以确定哪个 changelist 元素引起了错误。如果将 nevents 设置为零,则会得到错误代码,但没有指示哪个事件引起了错误。因此,使用 EV_RECEIPT 可以将 nevents 设置为非零值,而不会排空任何待处理事件。

好的,这很有道理,但它与我链接的苹果示例代码不符。该代码中的注释说:创建kqueue并设置其以监视SIGCHLD。使用新的10.5 EV_RECEIPT标志确保我们得到我们期望的内容 - 然而,它只调用了一个事件的kevent,使用了EV_RECEIPT,并且既没有检查kevent的返回值,也没有检查返回事件中的值。你知道“我们得到我们期望的内容”这句话的含义吗?还是在这种情况下使用EV_RECEIPT是虚假的? - davmac
在这种情况下,将nevents设置为零可以实现相同的行为,因为没有检查返回值。但是,在其他代码中可能会复制此模式,其中检查返回值。期望返回新过滤器而不是挂起事件。 - Richard Smith
这段代码是否完全有效呢,因为它没有检查事件列表中的错误?我似乎发现僵尸进程在尝试使用NOTE_EXIT将它们添加到kqevent时会返回ESRCH,但我找不到许多在线参考或文档来描述在这种情况下应该发生什么。 - user1712368

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接