記epoll_data_t中ptr使用的坑

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章