分類: 網路程式設計
2012-05-29 21:52
21人閱讀收藏
舉報(1)阻塞block
所謂阻塞方式block,顧名思義,就是程序或是執行緒執行到這些函式時必須等待某個事件的發生,如果事件沒有發生,程序或執行緒就被阻塞,函式不能立即返回。
例如socket程式設計中connect、accept、recv、recvfrom這樣的阻塞程式。
再如絕大多數的函式呼叫、語句執行,嚴格來說,他們都是以阻塞方式執行的。
(2)非阻塞non-block
所謂非阻塞方式non-block,就是程序或執行緒執行此函式時不必非要等待事件的發生,一旦執行肯定返回,以返回值的不同來反映函式的執**況,如果事件發生則與阻塞方式相同,若事件沒有發生則返回乙個**來告知事件未發生,而程序或執行緒繼續執行,所以效率較高。
比如程式語句:int len=read(fd,buffer,bufsize);函式read唯讀一次,不管讀到資料或是沒有讀到資料,它都返回結果。又如while(1),雖然可以迴圈讀取想要的資料,但它是非阻塞的,會大大地浪費系統資源。
備註:在socket程式設計中使用:fcntl(sockfd,f_setfl,o_nonblock);會把sockfd設定為非阻塞模式,則之後的connect、accept、recv、recvfrom等函式便失去了阻塞功能,變成了非阻塞函式。
(3)select函式
int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);
上面的非阻塞式的while迴圈顯然是不可取的,而失去阻塞功能的connect等函式也需要改進,對於這兩種情況,select函式便可以大顯身手了。
關於select函式在這方面的使用,已經有兩篇文章講得十分清楚了:
關於select函式的使用,有幾點需要注意的地方:
maxfdp 為所有fd中的最大值加1.
readfds 和 timeout 在每次執行select前都要重新初始化. 對於readfds,每次迴圈都要清空集合,否則不能檢測描述符變化;而對於timeout,每次都要初始化其值,否則timeout被預設初始化為0.
//正確使用select函式的典型示例(程式段):
int read(int fd, char *readbuf, int bufsize)
readbuf1[bufsize1-1]='\0';
readbuf2[bufsize2-1]='\0';
return len1+len2;
}
阻塞 非阻塞的概念和select函式的阻塞功能
1 阻塞block 所謂阻塞方式block,顧名思義,就是程序或是執行緒執行到這些函式時必須等待某個事件的發生,如果事件沒有發生,程序或執行緒就被阻塞,函式不能立即返回。例如socket程式設計中connect accept recv recvfrom這樣的阻塞程式。再如絕大多數的函式呼叫 語句執行...
阻塞 非阻塞的概念和select函式的阻塞功能
其它文件 1 阻塞block 所謂阻塞方式block,顧名思義,就是程序或是執行緒執行到這些函式時必須等待某個事件的發生,如果事件沒有發生,程序或執行緒就被阻塞,函式不能立即返回。例如socket程式設計中connect accept recv recvfrom這樣的阻塞程式。再如絕大多數的函式呼叫...
select與阻塞和非阻塞
這2天一直和同事在討論socket的非阻塞用在什麼場合,並且認為在select時,使用的socket要設定成阻塞的,今天在網上搜了一下,才發現,原來,我們搞錯了,乙個套接字阻塞或者不阻塞,select就在那裡,它可以針對這2種套接字使用,對任何一種套接字的輪詢檢測,超時時間都是有效的,區別就在於 當...