gpt4 book ai didi

linux - EPOLLONESHOT 是否阻止在对 epoll_wait() 的单个调用中返回单个描述符上的多个事件?

转载 作者:太空狗 更新时间:2023-10-29 11:32:00 25 4
gpt4 key购买 nike

关于 epoll_ctl(2) 的手册页关于 EPOLLONESHOT 标志有这样的说法:

Sets the one-shot behavior for the associated file descriptor.
This means that after an event is pulled out with
epoll_wait(2) the associated file descriptor is internally
disabled and no other events will be reported by the epoll
interface. The user must call epoll_ctl() with EPOLL_CTL_MOD
to rearm the file descriptor with a new event mask.

但是,尚不清楚事件是在插入事件数组之后还是在返回所有事件之后在 epoll_wait 中被禁用。

最佳答案

EPOLLONESHOT 的行为是这样的,在成功调用 epoll_wait(2) 之后在报告指定文件描述符的地方,epoll_wait(2) 将不会报告新事件在同一个文件描述符上,直到您使用 epoll_ctl(2) 显式重新激活它.您可以将其视为一种机制,一旦 epoll_wait(2) 返回文件描述符,便会暂时禁用它。 .

它不会阻止epoll_wait(2)在同一文件描述符的同一调用中返回多个事件 - 事实上,如果在调用时有多个事件可用,它们将全部合并到 events 中。领域struct epoll_event , 是否EPOLLONESHOT对该文件描述符有效。

换句话说,EPOLLONESHOT控制在什么条件下在对 epoll_wait(2) 的调用中报告 文件描述符;它不参与事件聚合和检测。

一个例子

下面的代码创建一对连接的套接字并写入一端。 sv[1]将可用于读取和写入。如您所见,添加或删除 EPOLLONESHOTEPOLLIN 的事实没有影响和 EPOLLOUT合并为一个事件。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/socket.h>

int main(void) {
int efd = epoll_create(1);
if (efd < 0) {
perror("epoll_create(2) error");
exit(EXIT_FAILURE);
}

int sv[2];
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0) {
perror("socketpair(2) error");
exit(EXIT_FAILURE);
}

const char str[] = "Hello, world!";
size_t to_write = sizeof(str)-1;
ssize_t written = write(sv[0], str, to_write);

if (written != to_write) {
if (written < 0) {
perror("write(2) error");
} else {
fprintf(stderr, "short write detected: %zd/%zu\n", written, to_write);
}
exit(EXIT_FAILURE);
}

struct epoll_event epevent;
epevent.events = EPOLLIN | EPOLLOUT | EPOLLONESHOT; // Try to remove EPOLLONESHOT here
epevent.data.fd = sv[1];

if (epoll_ctl(efd, EPOLL_CTL_ADD, sv[1], &epevent) < 0) {
perror("epoll_ctl(2) error");
exit(EXIT_FAILURE);
}

struct epoll_event events_arr[16];
int events = epoll_wait(efd, events_arr, sizeof(events_arr)/sizeof(*events_arr), -1);
if (events < 0) {
perror("epoll_wait(2) error");
exit(EXIT_FAILURE);
}

int i;
for (i = 0; i < events; i++) {
printf("Event %d: ", i);
if (events_arr[i].events & EPOLLIN)
printf("EPOLLIN ");
if (events_arr[i].events & EPOLLOUT)
printf("EPOLLOUT ");
printf("\n");
}

return 0;
}

关于linux - EPOLLONESHOT 是否阻止在对 epoll_wait() 的单个调用中返回单个描述符上的多个事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32464818/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com