- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
关于事件是否合并的文档并不清楚,我的测试表明它们在某些情况下存在,但并非总是如此。
考虑 man 7 epoll
:
Since even with edge-triggered epoll, multiple events can be generated upon receipt of multiple chunks of data, the caller has the option to specify the EPOLLONESHOT flag...
和问答部分:
Q7 If more than one event occurs between epoll_wait(2) calls, are they combined or reported separately?
A7 They will be combined.
我假设手册中的第一个语句意味着在从套接字读取数据包到达,您读取它,然后另一个数据包到达等情况下,您可以接收多个 EPOLLIN 事件。问答部分的答案是谈论不同的事件,如 EPOLLIN 和 EPOLLOUT。如果我错了,请纠正我。
我正在研究一些代码,以便更好地理解 epoll 的工作原理,它似乎根据是否设置了另一个事件而对同一类型的事件表现不同。更准确地说,如果我只等待 EPOLLIN,多个输入将生成一个事件,但如果我同时等待 EPOLLIN 和 EPOLLOUT,则多个输入将生成多个事件。
这是我用来测试的代码:
#include <stdio.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
struct epoll_event ev = {EPOLLIN|EPOLLOUT|EPOLLET};
int epoll = epoll_create1(0);
epoll_ctl(epoll, EPOLL_CTL_ADD, 0, &ev);
//async stdin
int flags = fcntl(0, F_GETFL);
flags |= O_NONBLOCK;
fcntl(0, F_SETFL, flags);
while(1){
struct epoll_event events[64];
int n = epoll_wait(epoll, events, 64, -1);
printf("Event count: %d\n", n);
if(events[0].events == EPOLLIN)
printf("EPOLLIN only\n\n");
else
if(events[0].events == (EPOLLIN|EPOLLOUT))
printf("EPOLLIN and EPOLLOUT\n\n");
else
printf("EPOLLOUT only\n\n");
char buffer[256];
read(0, buffer, 256);
sleep(1);
}
return 0;
}
按下回车后的输出显示同时收到了 EPOLLIN 和 EPOLLOUT,此消息出现的次数与按下回车的次数相同,然后显示仅生成了 EPOLLOUT。
但是如果不带EPOLLOUT标志编译程序,多次回车,单个事件只会报一次。
如果我删除 read
调用,则在设置 EPOLLOUT 时会继续报告 EPOLLIN,但在仅设置 EPOLLIN 时则不会。
行为是否取决于它正在等待的事件或我的测试代码有问题?如果是依赖,我能保证以后不会变吗?
最佳答案
我相信您正在观察未定义行为的影响,因为您在滥用 API。
具体来说,您正在将 STDIN_FILENO
(即 0
)传递给 epoll_ctl
并要求等待 EPOLLOUT
在只读的文件描述符上。可能发生的情况是操作系统试图告诉您文件描述符的写入方向有问题。
另外,当使用边缘触发模式时,您应该继续您的 I/O,直到您看到 EAGAIN
。当操作不再阻塞时,epoll_wait
调用返回。
我修改了您的程序以改为使用套接字,并从套接字读取数据直到 EAGAIN
,它的行为符合我的预期。
在我的版本中,我创建了一对套接字,以及一个从 STDIN_FILENO
读取并写入一对套接字之一的线程。 main
主体循环然后在另一个套接字上执行 epoll_wait
。
当我启动程序时,它会在第一次调用 epoll_wait
时返回以报告可写,但会在下一次迭代时阻塞:
Event count: 1
EPOLLOUT only
当我键入输入时,它报告可读和可写,然后在下一次迭代中阻塞 epoll_wait
,正如预期的那样:
asdf
Event count: 1
EPOLLIN and EPOLLOUT
我使用的代码如下。一、线程:
static void * iothread (void *svp) {
int *sv = svp;
char buf[256];
ssize_t r;
again:
while ((r = read(0, buf, sizeof(buf))) > 0) {
ssize_t n = r;
const char *p = buf;
while (n > 0) {
r = write(sv[1], p, n);
if (r < 0) {
if (errno == EINTR) continue;
break;
}
n -= r;
p += r;
}
if (n > 0) break;
}
if (r < 0 && errno == EINTR) {
goto again;
}
close(sv[1]);
return NULL;
}
然后,主体
主体:
int main(int argc, char* argv[]) {
int sv[2];
struct epoll_event ev = {EPOLLIN | EPOLLOUT | EPOLLET};
int epoll = epoll_create1(0);
pthread_t t;
socketpair(AF_LOCAL, SOCK_STREAM, 0, sv);
pthread_create(&t, NULL, iothread, sv);
epoll_ctl(epoll, EPOLL_CTL_ADD, sv[0], &ev);
while(1){
struct epoll_event events[64];
int n = epoll_wait(epoll, events, 64, -1);
printf("Event count: %d\n", n);
if(events[0].events == EPOLLIN)
printf("EPOLLIN only\n\n");
else
if(events[0].events == (EPOLLIN|EPOLLOUT))
printf("EPOLLIN and EPOLLOUT\n\n");
else
printf("EPOLLOUT only\n\n");
char buffer[256];
ssize_t r;
again:
r = recv(sv[0], buffer, 256, MSG_DONTWAIT);
if (r > 0) goto again;
if (r < 0 && errno == EAGAIN) {
sleep(1);
continue;
}
break;
}
return 0;
}
关于c - 为什么 EPOLLOUT 会改变 EPOLLIN 的处理方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36302580/
我有以下MWE function f(p) ans = zeros(p, 2) return ans end ans = f(2) ans b=ans.+1.0 ans 起初,ans是正确的,
OWIN AppBuilder“UseStatic”位从本地文件系统传送文件,这在某些情况下很方便,但我希望它从我在应用程序启动时预先填充的内存中 IDictionary 传送内容。任何人都可以指出一
我是 JavaScript 新手。 我的代码允许我列出 JSON 文档的元素及其类型,并将所有元素连接到一个字符串 donnees_types 中。 问题是 JavaScript 中的 typeof
我想在每次刷新时更改主页上的背景图像。我怎样才能做到这一点?我认为 jquery 是可能的,但我不太清楚。 感谢您对此主题的任何帮助或评论。 最佳答案 我不知道“如何”,但我找到了以下链接: http
所以我已经在这上面花了几个小时了,老实说我完全陷入困境。我写了一个 for 循环来计算整数中的数字数量,但我发现一旦我输入 10 位以上的数字,除数值就会发生变化,而且我不明白为什么。我在互联网上搜索
当我在使用表面 View 的游戏 Activity 和使用膨胀菜单的其他 Activity 之间切换时,我会收到错误消息。 日志猫: 07-13 15:15:34.464: ERROR/Android
听说很简单 R*=f; G*=f; B*=f; 其中 f 是标量值 0 .. 1.0 或更大改变亮度的方法不太正确颜色,但我找不到一些代码片段获得更好的东西(无需太多学习色彩理论)也许有人可以在这里给
如以下链接所述:- How to get the ThreadPoolExecutor to increase threads to max before queueing? 我将队列实现更改为在进入
我只显示最初提供 20 分钟 slotMinutes 的日历。我试图让用户即时更改为 10 分钟的 slotMinutes。 我有一个触发以下代码的按钮: $('#calendar').fullCal
我的问题是:我的应用程序中有一个新闻列表(UITableView)当我点击 1 个"new"时,我打开它,里面有一个后退按钮,可以让我回到列表。现在的问题是我必须在滑动时实现"new"更改,所以我制作
我面临着与 I'm trying to install psycopg2 onto Mac OS 10.6.3; it claims it can't find "stdarg.h" but I ca
需要通过为 array2 中不存在的索引设置 visible false 来从 array1 创建一个新的 array3。 在下面的示例中,我有索引 0,2。所以对于 1,3,结果数组必须具有 vis
我有一个对象,类似这样 var Egg = function(){ this.test = $(.slider .label); $('.slider').slider({
我想改变 ScrollView 的宽度。首先,我这样做了: var scrollWidthConstraint: NSLayoutConstraint! 然后设置它: scrollWidthConst
我有两个动画,一个是“过渡”,它在悬停时缩小图像,另一个是 animation2,其中图像的不透明度以周期性间隔重复变化。 我有 animation2 在图像上进行,当我将鼠标悬停在它上面时,anim
我是一个 jQuery 新手,一直在尝试添加一个脚本来更改 div onClick 的 id。 这是一个jsfiddle example . $(function accept() { $("
我正在尝试更改用户输入的字母的大小写,并将该字母的小写和大写版本存储在变量中。我已经编写了下面的代码,但它在运行时遇到了问题。有人指出是什么导致了问题吗? #include #include #i
假设我有这段代码: char num[2] = {15, 240}; char* p_num; 现在,如果我理解的一切正确,数组中的位应该像这样对齐: 00001111 11110000 我的问题是
var html = '' + count + '' + i.Description + '' + i.Priority + '' + i.Status + 'johnsmith- ' + creat
我在虚拟机上安装了 minix3,并希望我可以操纵当前的队列选择算法,以便我可以将其从优先级顺序更改为包括随机分类的低优先级作业的优先级顺序。我发现我需要更改的代码部分在 proc.c 中,具体部分是
我是一名优秀的程序员,十分优秀!