epoll是kernel 2.6後新加入的事件機制,在高併發條件下,遠優於select.
用個硬體中的例子吧,可能不太恰當:epoll相當於i/o中斷(有的時候才相應),而select相當於輪詢(總要反覆查詢)。
其實epoll比slect好用很多,主要一下幾個用法。
struct epoll_event ; epoll事件體,事件發生時候你可以得到乙個它。其中epoll_event.data.fd可以儲存關聯的控制代碼,epoll_event.event是監聽標誌,常用的有epollin (有資料,可以讀)、epollout(有資料,可以寫)epollet(有事件,通用);
(1)建立epoll控制代碼
int epfd = epoll_create(epoll_size);
(2)加入乙個控制代碼到epoll的監聽佇列
ev.data.fd = serverfd;
ev.events = epollin | epollet;
epoll_ctl(epfd, epoll_ctl_add, serverfd, &ev);
上面的fd是你要繫結給事件發生時候使用的fd,到時候只能操作這個,下面是事件型別。
使用epoll_ctl新增到之中,epoll_ctl_add是epoll控制型別,這裡監聽的fd和給event的fd一般相同。
(3)等待event返回
int nfds = epoll_wait(epfd, evs, event_arr, -1);
傳入的evs是epoll_event的陣列,event_arr應當是不超過這個陣列的長度。返回nfds的是不超過event_arr的數值,表示本次等待到了幾個事件。
(4)遍歷事件
注意,這裡遍歷的事件是肯定已經發生了的,而select中遍歷的是每個fd,而fd不一定在fdset中(即不一定有讀事件發生)!這是效率最大的差別所在!
for (int i = 0; i < nfds; i++)
(5)其他技巧
對事件是否是serverfd判斷,如果是,進行accept並加入epoll監聽佇列,要設定非同步讀取。
如果evts[i]&epollin,表示可讀,使用read進行試探,如果》0表示連線沒有關閉,否則連線已經關閉(出發事件又讀取不到東西,表示socket關閉!)。如果<0出錯。如果》0,需要繼續讀取直到為0,但是注意這裡的為0是在第一次read不為0的前提下,畢竟我們設定了非同步讀取,暫時沒有資料可以讀就返回0了!而如果第一次返回0,那麼就是關閉吧!
注意關閉要移出出epoll並且close(clientfd)
羅嗦了好多,看**!
**:
PHP用POPEN非同步執行,碰見ECHO時會終止
php程式中,我們常用popen來非同步執行,但是如果非同步指令碼中有echo輸出,則會在此行終止。下面舉例 非同步執行run.php for i 0 i 5 i echo finish r n 在命令列中執行指令碼 輸出正常。a.txt中內容也正常。但是如果php中用popen來非同步執行,就會出...
關於epoll檢測非同步連線的方法
因為epoll本身沒有明確提出當非同步connect成功之後會返回什麼樣的訊號,通過測試有如下結果 1,當本地還沒呼叫connect函式,卻將套接字送交epoll檢測,epoll會產生一次 epollout epollhup,也就是產生乙個值為0x14的events.2,當本地connect事件發生...
C 用委託實現非同步,非同步與多執行緒的異同
多執行緒和非同步操作的異同 多執行緒和非同步操作兩者都可以達到避免呼叫執行緒阻塞的目的,從而提高軟體的可響應性。甚至有些時候我們就認為多執行緒和非同步操作是等同的概念。但是,多執行緒和非同步操作還是有一些區別的。而這些區別造成了使用多執行緒和非同步操作的時機的區別。非同步操作的本質 所有的程式最終都...