先簡單比較一下level trigger 和 edge trigger 模式的不同。
讓我們換乙個角度來理解et模式,事實上,epoll的et模式其實就是socket io完全狀態機。
當socket由不可讀變成可讀時,epoll的et模式返回read 事件。對於read 事件,開發者需要保證把讀取緩衝區資料全部讀出,man epoll可知:
示例**
需要讀者注意的是,socket模式是可寫的,因為傳送緩衝區初始時空的。故應用層有資料要傳送時,直接呼叫write系統呼叫傳送資料,若write系統呼叫返回ewouldblock則表示socket變為不可寫,或者write系統呼叫返回的數值小於傳入的buffer引數的大小,這時需要把未傳送的資料暫存在應用層待傳送列表中,等待epoll返回write事件,再繼續傳送應用層待傳送列表中的資料,同樣若應用層待傳送列表中的資料沒有一次性發完,那麼繼續等待epoll返回write事件,如此迴圈往復。所以可以反推得到如下結論,若應用層待傳送列表有資料,則該socket一定是不可寫狀態,那麼這時候要傳送新資料直接追加到待傳送列表中。若待傳送列表為空,則表示socket為可寫狀態,則可以直接呼叫write系統呼叫傳送資料。總結如下:
示例**:
void socket_impl_t::send_impl(const string& src_buff_)//! socket buff is full, cache the data
if (false == m_send_buffer.empty())
string left_buff;
int ret = do_send(buff_, left_buff);
if (ret < 0)
else if (ret > 0)
else
}int socket_impl_t:: handle_epoll_write ()
doelse if (ret > 0)
else
} while (false == m_send_buffer.empty());
m_sc->handle_write_completed(this);
return 0;
}
lt模式主要是讀操作比較簡單,但是對於et模式並沒有優勢,因為將讀取緩衝區資料全部讀出並不是難事。而write操作,et模式則流程非常的清晰,按照完全狀態機來理解和實現就變得非常容易。而lt模式的write操作則複雜多了,要頻繁的維護epoll的wail列表。
在**編寫時,把epoll et當成狀態機,當socket被建立完成(accept和connect系統呼叫返回的socket)時加入到epoll列表,之後就不用在從中刪除了。為什麼呢?man epoll中的faq告訴我們,當socket被close掉後,其自動從epoll中刪除。對於監聽socket簡單說幾點注意事項:
示例**:
int acceptor_impl_t::handle_epoll_read()github :else if (errno == eintr || errno == emfile || errno == econnaborted || errno == enfile ||
errno == eperm || errno == enobufs || errno == enomem)
perror("accept");
return -1;
}socket_i* socket = create_socket(new_fd);
socket->open();
} while (true);
return 0;
}
ffrpc 介紹:
對於監聽的socket檔案描述符我們用sockfd表示,對於accept()返回的檔案描述符(即要讀寫的檔案描述符)用connfd表示。
五.總結
1.對於監聽的sockfd,最好使用水平觸發模式,邊緣觸發模式會導致高併發情況下,有的客戶端會連線不上。如果非要使用邊緣觸發,網上有的方案是用while來迴圈accept()。
2.對於讀寫的connfd,水平觸發模式下,阻塞和非阻塞效果都一樣,不過為了防止特殊情況,還是建議設定非阻塞。
3.對於讀寫的connfd,邊緣觸發模式下,必須使用非阻塞io,並要一次性全部讀寫完資料(用while來迴圈讀)。
參考c/servermode/epollserver.c中如何使用epoll進行
epoll 水平觸發 邊緣觸發
水平觸發 只要緩衝區還有資料,核心就還會通知使用者。使用者如果第一次讀取資料沒讀完,即使沒有任何新的操作觸發,還是可以繼續通過epoll wait來獲取事件 邊緣觸發 只有當新事件觸發的時候,才能通過epoll wait來獲取資料,如果第一次讀取資料沒讀完,就只能等待下一次事件觸發來獲取餘下的資料。...
epoll 水平觸發與邊緣觸發
epoll也是實現i o多路復用的一種方法,為了深入了解epoll的原理,我們先來看下epoll水平觸發 level trigger,lt,lt為epoll的預設工作模式 與邊緣觸發 edge trigger,et 兩種工作模式。使用脈衝訊號來解釋lt和et可能更加貼切。level是指訊號只需要處於...
epoll的水平觸發和邊緣觸發
即level triggered and edge triggered 簡單說來 level triggered 只要事件是處於就緒狀態,你每詢問一次,就告訴你一次它處於就緒狀態。edge triggered 只有在狀態改變的時候告訴你,這也是為什麼et模式下,建議用非阻塞的socket。下面我們來...