水平觸發通知又叫“低速模式”,是linux epoll模型的默認方式。對於此方式《Linux/Unix系統編程手冊(下冊)》中的解釋是:如果文件描述符上可以非阻塞地執行I/O系統調用,此時認為它已經就緒。
對此,我的理解是:某個I/O實踐就緒,例如,文件緩沖區收到了5個字節的數據,此時此文件描述符可讀,觸發epoll可讀事件。但是如果就緒的文件描述符是非阻塞的(也就是說中途可以被打斷),當讀取三個字節的時候被別的事件打斷了,下次仍然觸發此描述符的可讀事件,會接著讀上次沒讀完的兩個字節。
邊沿觸發通知又叫”高速模式“(ET),書上的解釋是:如果文件描述符自上次狀態檢查以來有了新的I/O活動(比如新的輸入),此時需要觸發通知。
我的理解是:拿可讀事件來說,如果文件緩沖區收到了5個字節的數據,觸發通知,開始讀取緩沖區數據,如果此文件描述符仍然是非阻塞的,被別的信號打斷後,未來得及讀取的數據將丟失,只有下次再有新的數據加入緩沖區後,再次觸發通知,讀取新的數據。因此使用"ET模式"時需要盡可能多的讀取或者寫入數據。
設置EPOLL 為ET 模式的方法:
struct epoll_event ev;
ev.data.fd = fd;
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epoll_fd,EPOLL_ZTL_ADD,fd, &ev);
設置文件為非阻塞模式的方法:
主要使用如下兩個函數獲取文件的flags,即open函數的第二個參數:
flags = fcntl(fd,F_GETFL,0);
設置文件的flags:
fcntl(fd,F_SETFL,flags);
設置方法
flags = fcntl(fd,F_GETFL,0);
flags |= O_NONBLOCK;
fcntl(fd,F_SETFL,flags);
或者一步到位的方式:
fcntl(socket,F_SETFL,fcntl(socket,F_GETFL)|O_NONBLOCK);