本文主要是测试epoll监测多个fd时,当一个fd激活并进行对应处理时,此时另外一个fd被激活,新激活的fd是否会丢失?答案是不会,会在处理完前一个fd后马上处理另外一个fd。
可能问题比较蠢,但是有时想不通,就想验证一下。
下面是例子,
例子
代码如下,
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <thread>
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
bool fRunning = true;
int gEventfd = -1;
int gEventfd2 = -1;
void sig_handler(int signum)
{
fRunning = false;
exit(0);
}
void thr_func()
{
int epollfd = epoll_create1(EPOLL_CLOEXEC);
if (epollfd == -1)
{
handle_error("epoll_create1");
}
struct epoll_event evEvent;
evEvent.events = EPOLLIN;
evEvent.data.fd = gEventfd;
epoll_ctl(epollfd, EPOLL_CTL_ADD, gEventfd, &evEvent);
struct epoll_event evEvent2;
evEvent2.events = EPOLLIN;
evEvent2.data.fd = gEventfd2;
epoll_ctl(epollfd, EPOLL_CTL_ADD, gEventfd2, &evEvent2);
struct epoll_event events[2];
uint64_t exp = 0;
int result = 0;
while (fRunning)
{
int nfd = epoll_wait(epollfd, events, 2, -1);
if (nfd > 0)
{
printf("==> start dealing...\n");
for (int i = 0; i < nfd; ++i)
{
exp = 0;
result = 0;
if (events[i].data.fd == gEventfd)
{
result = read(gEventfd, &exp, sizeof(uint64_t));
if (result == sizeof(uint64_t))
{
if (exp == 100)
{
printf("==> XXX\n");
sleep(5);
printf("==> yyy\n");
}
}
}
else if (events[i].data.fd == gEventfd2)
{
result = read(gEventfd2, &exp, sizeof(uint64_t));
if (result == sizeof(uint64_t))
{
if (exp == 200)
{
printf("==> XXX2\n");
}
}
}
}
}
}
}
void writeEventFd()
{
uint64_t u = 100;
write(gEventfd, &u, sizeof(uint64_t));
sleep(1);
u = 200;
write(gEventfd2, &u, sizeof(uint64_t));
}
int main(void)
{
signal(SIGINT, sig_handler);
gEventfd = eventfd(0, 0);
if (gEventfd < 0)
{
return -1;
}
gEventfd2 = eventfd(0, 0);
if (gEventfd2 < 0)
{
return -1;
}
std::thread t1(thr_func);
std::thread t2(writeEventFd);
t1.join();
t2.join();
return 0;
}
代码中开启了2个线程t1和t2,t1使用epoll监测2个eventfd,第一个fd的处理函数会延时6秒;t2会先向第一个fd发送通知,过1秒后向第二个fd发送通知。这样在执行第一个fd的处理函数时,第二个fd的通知也会到来。
打印如下, 可以看到当第一个fd的处理函数执行完毕后,会马上执行第二个fd的处理函数,不会丢失。
|