先看一下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時,只能給其中一個元素賦值,看自己的代碼實現對哪個賦值的效果最好。