linux下epoll模型accept並發問題__linux

來源:互聯網
上載者:User

最近用c++實現了貝葉斯分類演算法,做了個自動識別垃圾資訊的小工具。工具中有個功能,通過綁定指定連接埠,和用戶端通訊。服務端使用的是epoll網路模型。在測試的時候發現,單使用者的情況下用戶端和伺服器通訊正常。但是在多使用者並發的情況下,用戶端和服務端通訊不正常。此時,用戶端能正常的連結,發送資料,但是一直卡在接收資料部分。如下圖:

出現這種問題,是因為不正確的使用了epoll中的ET(edge-trigger)模式。代碼如下:

01 /**************************************************
02 函數名:acceptConn
03 功能:接受用戶端的連結
04 參數:srvfd:監聽SOCKET
05 ***************************************************/
06 void acceptConn(int srvfd)
07 {
08 struct sockaddr_in sin;
09 socklen_t len = sizeof(struct sockaddr_in);
10 bzero(&sin, len);
11  
12 int confd = accept(srvfd, (struct sockaddr*)&sin, &len);
13  
14 if (confd < 0)
15 {
16 printf("%s: bad accept\n");
17 return;
18 }else
19 {
20 printf("Accept Connection: %d", confd);
21 }
22  
23 setNonblocking(confd);
24  
25 //將建立立的串連添加到EPOLL的監聽中
26 struct epoll_event event;
27 event.data.fd = confd;
28 event.events =  EPOLLIN|EPOLLET;
29 epoll_ctl(epollfd, EPOLL_CTL_ADD, confd, &event);
30 }

注意倒數第二行:event.events = EPOLLIN|EPOLLET; 採用的是ET模式。下面我們來具體說下,問題出在那裡。

在epoll中有兩種模式:level-trigger模式,簡稱LT模式,和edge-trigger模式,簡稱ET模式。其中,LT是預設的工作模式。

這兩種模式的工作方式有些不同。在level-trigger模式下只要某個socket處於readable/writable狀態,無論什麼時候進行epoll_wait都會返回該socket;而edge-trigger模式下只有某個socket從unreadable變為readable或從unwritable變為writable時,epoll_wait才會返回該socket。

在ET模式socket非阻塞的情況下(上面代碼中就是這種情況),多個串連同時到達,伺服器的TCP就緒隊列瞬間積累多個就緒串連,由於是邊緣觸發模式,epoll只會通知一次,accept只處理一個串連,導致TCP就緒隊列中剩下的串連都得不到處理。因此,就出現了上面所提及的問題。

解決辦法是用while迴圈抱住accept調用,處理完TCP就緒隊列中的所有串連後再退出迴圈。如何知道是否處理完就緒隊列中的所有串連呢。accept返回-1並且errno設定為EAGAIN就表示所有串連都處理完。

修改後的代碼如下:

01 /**************************************************
02 函數名:acceptConn
03 功能:接受用戶端的連結
04 參數:srvfd:監聽SOCKET
05 ***************************************************/
06 void acceptConn(int srvfd)
07 {
08 struct sockaddr_in sin;
09 socklen_t len = sizeof(struct sockaddr_in);
10 bzero(&sin, len);
11 int confd = 0;
12 while((confd = accept(srvfd, (struct sockaddr*)&sin, &len)) > 0) {
13

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.