先看一下epoll_data_t的结构
typedef union epoll_data
{
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
struct epoll_event
{
uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
对于union联合体概念不是很懂得同学可以看看
一般我们先会给epoll_event中的data进行赋值,然后再epoll_wait返回后取出来进行使用,今天我就犯了一个很低级的问题,我同时对epoll_data_t中的fd 和ptr都进行了赋值,那会产生怎么样的结果呢?
int timefd = ....;
int* a = new int(1);
int epollfd = epoll_create1(EPOLL_CLOEXEC);
struct epoll_event events[126];
struct epoll_event event;
event.data.fd = timefd;
event.data.ptr = a;
event.events = EPOLLIN | EPOLLET;
然后我们用epoll_wait测试一下
while(true)
{
int num = epoll_wait(epollfd, events, 126, 0);
assert(num >= 0);
for(int i = 0; i < num; ++i)
{
if(events[i].events & EPOLLIN)
{
int fd = events[i].data.fd;
int* value = static_cast<int*>(events[i].data.ptr);
std::cout << *value << "\n";
if(*fd == timefd)
{
s = read(*fd, &exp, sizeof(uint64_t));
assert(s == sizeof(exp));
std::cout << "time expired\n";
}
}
}
}
结果呢?if语句从来没有判断成功过?为什么呢?
- 因为我们首先给data.fd进行赋值,然后又对data.ptr进行赋值,这个时候data.fd就没有任何意义了,所以返回的就是一个无意义的数字,if进行判断的时候永远不可能成功。
那我们如果先给data.ptr赋值,然后再给data.fd赋值会产生什么样的结果?
结果就是和上述情况反过来,指针无意义,就会产生段错误。
所以在使用epoll_data_t时,只能给其中一个元素赋值,看自己的代码实现对哪个赋值的效果最好。