epoll_wait 直到按下回车才醒来
epoll_wait doesn't wake up until pressing on enter
我是 epoll 新手。
我的代码工作正常。 epoll 正在存储我的文件描述符并等待文件描述符为 "ready"。
但是,出于某种原因,直到我按下回车键它才会醒来(即使数据已经接收到 fd,并且在回车后我会立即看到之前发送的所有数据)。
一次输入后它将按预期工作(不需要输入,当 fd 再次准备好时它将再次唤醒)。
这是我的代码的本质:
int nEventCountReady = 0;
epoll_event event, events[EPOLL_MAX_EVENTS];
int epoll_fd = epoll_create1(0);
if(epoll_fd == -1)
{
std::cout << "Error: Failed to create EPoll" << std::endl;
return ;
}
event.events = EPOLLIN;
event.data.fd = myfd;
if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, 0, &event))
{
fprintf(stderr, "Failed to add file descriptor to epoll\n");
close(epoll_fd);
return ;
}
while(true)
{
std::cout << "Waiting for messages" << std::endl;
nEventCountReady = epoll_wait(epoll_fd, events, EPOLL_MAX_EVENTS, 30000); << Stuck until Enter will be pressed (at first while loop)
for(int i=0; i<nEventCountReady; i++)
{
msgrcv(events[i].data.fd, oIpCMessageContent, sizeof(SIPCMessageContent), 1, 0);
std::cout << oIpCMessageContent.buff << std::endl;
}
}
这个
if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, 0, &event))
应该是
if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, myfd, &event))
在第一行中,您告诉 epoll 监视通常是标准输入的 fd 0。这就是它等待它的原因,例如为您输入。
请注意,您的原始代码只是巧合。碰巧当您输入 myfd
中有数据时(即使有 none msgrcv
块)。一旦您按下 Enter 键,它就会一直唤醒,因为 epoll 知道 STDIN 已准备就绪,但您没有从中读取。
感谢 kamilCuk,我注意到 msgget 并不像我想的那样 return 文件描述符。
它 return 是 "System V message queue identifier"。
而且正如之前所说的那样,System V 消息队列不适用于像 epoll 这样的选择器。
我是 epoll 新手。 我的代码工作正常。 epoll 正在存储我的文件描述符并等待文件描述符为 "ready"。 但是,出于某种原因,直到我按下回车键它才会醒来(即使数据已经接收到 fd,并且在回车后我会立即看到之前发送的所有数据)。 一次输入后它将按预期工作(不需要输入,当 fd 再次准备好时它将再次唤醒)。
这是我的代码的本质:
int nEventCountReady = 0;
epoll_event event, events[EPOLL_MAX_EVENTS];
int epoll_fd = epoll_create1(0);
if(epoll_fd == -1)
{
std::cout << "Error: Failed to create EPoll" << std::endl;
return ;
}
event.events = EPOLLIN;
event.data.fd = myfd;
if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, 0, &event))
{
fprintf(stderr, "Failed to add file descriptor to epoll\n");
close(epoll_fd);
return ;
}
while(true)
{
std::cout << "Waiting for messages" << std::endl;
nEventCountReady = epoll_wait(epoll_fd, events, EPOLL_MAX_EVENTS, 30000); << Stuck until Enter will be pressed (at first while loop)
for(int i=0; i<nEventCountReady; i++)
{
msgrcv(events[i].data.fd, oIpCMessageContent, sizeof(SIPCMessageContent), 1, 0);
std::cout << oIpCMessageContent.buff << std::endl;
}
}
这个
if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, 0, &event))
应该是
if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, myfd, &event))
在第一行中,您告诉 epoll 监视通常是标准输入的 fd 0。这就是它等待它的原因,例如为您输入。
请注意,您的原始代码只是巧合。碰巧当您输入 myfd
中有数据时(即使有 none msgrcv
块)。一旦您按下 Enter 键,它就会一直唤醒,因为 epoll 知道 STDIN 已准备就绪,但您没有从中读取。
感谢 kamilCuk,我注意到 msgget 并不像我想的那样 return 文件描述符。 它 return 是 "System V message queue identifier"。
而且正如之前所说的那样,System V 消息队列不适用于像 epoll 这样的选择器。