select、pselect用於同步i/o多路復用。select、pselect允許程式同時監聽多個fd,直到其中乙個或多個fd上有對應的i/o操作就緒時,或超時時才返回。
/* fd_set for select and pselect. */
typedef
struct
fd_set;
fd_set採用bitset方式來儲存設定的fd,這種方式在有效fd數量較少時存在較大的浪費。fd_set有最大連線數限制,即最大連線數為__fd_setsize。如果fd的值太大則會出現陣列記憶體溢位的風險。
struct timeval
;
struct timespec
;
輔助巨集函式有fd_clr/fd_isset/fd_set/fd_zero,這些巨集函式主要是用於對fd_set的成員__fds_bits進行bitset操作。巨集函式的詳細定義見標頭檔案:/usr/include/sys/select.h和/usr/include/bits/select.h。
void
fd_clr
(int fd, fd_set *set)
;
從集合set中刪除fd
int
fd_isset
(int fd, fd_set *set)
;
判斷集合set中是否已經設定了fd
void
fd_set
(int fd, fd_set *set)
;
將fd新增到集合set中
void
fd_zero
(fd_set *set)
;
清空整個集合set
posix.1-2001之後
/* according to posix.1-2001 */
#include
早期版本
/* according to earlier standards */
#include
#include
#include
int
select
(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout)
;
允許程式同時監聽多個fd的i/o事件是否就緒,當乙個或多個fd上有i/o事件就緒時則返回,否則會等到超時後才返回。
引數說明
nfds:nfds的值等於readfds、writefds、exceptfds三個集合中編號最高的fd的值再+1。
readfds:輸入監聽的所有讀事件的fd集合,輸出觸發了讀事件的所有fd集合。輸出fd集合是輸入fd集合的子集。
writefds:輸入監聽的所有寫事件的fd集合,輸出觸發了寫事件的所有fd集合。輸出fd集合是輸入fd集合的子集。
exceptfds:輸入監聽的所有異常事件的fd集合,輸出觸發了異常事件的所有fd集合。輸出fd集合是輸入fd集合的子集。
timeout:select等待超時時間。如果傳入null,則阻塞等待,直到有對應的事件發生才返回;否則最多等待timeout指定的超時時間。
返回值說明
成功返回大於等於0,返回大於0表示三個fd集合中觸發事件的fd的總個數,等於0表示等待超時;錯誤返回-1,錯誤碼從errno中獲取。
錯誤碼說明
ebadf:某個fd集合中新增了無效的fd。
eintr:被訊號中斷。
einval:引數非法。nfds小於0,或timeout是無效的。
enomem:記憶體不足錯誤,導致沒有記憶體用於select內部使用。
說明:對集合readfds、writefds、exceptfds的所有操作必須使用巨集函式fd_clr、fd_isset、fd_set、fd_zero。
檢查當前系統中的glibc庫是否支援pselect介面的方法是檢查對應的巨集_posix_c_source或_xopen_source的值。具體示例**如下:
#if _posix_c_source >= 200112l || _xopen_source >= 600
/* can use pselect */
#else
/* can't use pselect */
#endif
#include
int
pselect
(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds,
const
struct timespec *timeout,
const sigset_t *sigmask)
;
允許程式同時監聽多個fd的i/o事件是否就緒,當乙個或多個fd上有i/o事件就緒時則返回,否則會等到超時後才返回。
引數說明
nfds:nfds的值等於readfds、writefds、exceptfds三個集合中編號最高的fd的值再+1。
readfds:輸入監聽的所有讀事件的fd集合,輸出觸發了讀事件的所有fd集合。輸出fd集合是輸入fd集合的子集。
writefds:輸入監聽的所有寫事件的fd集合,輸出觸發了寫事件的所有fd集合。輸出fd集合是輸入fd集合的子集。
exceptfds:輸入監聽的所有異常事件的fd集合,輸出觸發了異常事件的所有fd集合。輸出fd集合是輸入fd集合的子集。
timeout:select等待超時時間。如果傳入null,則阻塞等待,直到有對應的事件發生才返回;否則最多等待timeout指定的超時時間。
sigmask:指向乙個設定了訊號掩碼資訊的結構。如果不為null,則pselect先將當前的訊號掩碼替換成sigmask指向的訊號掩碼,再執行select,最後再替換會原來的訊號掩碼。
返回值說明
成功返回大於等於0,返回大於0表示三個fd集合中觸發事件的fd的總個數,等於0表示等待超時;錯誤返回-1,錯誤碼從errno中獲取。
錯誤碼說明
ebadf:某個fd集合中新增了無效的fd。
eintr:被訊號中斷。
einval:引數非法。nfds小於0,或timeout是無效的。
enomem:記憶體不足錯誤,導致沒有記憶體用於select內部使用。
說明:對集合readfds、writefds、exceptfds的所有操作必須使用巨集函式fd_clr、fd_isset、fd_set、fd_zero。
對pselect的支援對系統和glibc庫有要求,所以使用是必須進行對應編譯巨集檢查,必須要_posix_c_source>=200112l或_xopen_source>=600時才能使用。select則沒有這些限制。
select的timeout引數使用的是struct timeval,精度為微秒。pselect的timeout引數使用的是struct
timespec,精度為納秒。看似pselect超時精度更高,但由於其底層實現是復用的select,所以最後還是會轉換成struct timeval,所以其精度是一樣的。
select返回時會修改timeout的值為其剩餘時間,從而可以得到一次select所消耗的時間。pselect返回時不會修改timeout的值。
pselect有sigmask引數,而select沒有。
所在標頭檔案
#include
struct timeval
;
struct timespec
;
#include
#include
#include
#include
#include
#include
intmain
(void)}
else
printf
("no data within five seconds.\n");
exit
(exit_success)
;}
#include
#include
#include
#include
#include
#include
intmain
(void)}
else
printf
("no data within five seconds.\n");
exit
(exit_success)
;}
winsock i o的select模型的學習
include include include pragma comment lib,ws2 32.lib bool insertsock socket psock,socket sock if nindex fd setsize 1 return false return true int mai...
阻塞函式和select
阻塞方式 block,顧名思義,就是程序或是執行緒執行到這些函式時必須等待某個事件發生,如果事件沒有發生,程序或執行緒就被阻塞,函式不能立即返回。非阻塞方式 non block,就是程序或執行緒執行此函式時不必非要等待事件的發生,一旦執行肯定返回,以返回值的不同來反映函式的執 況。如果事件發生則與阻...
for和select迴圈語句
第一種for迴圈語句 for 變數名 in 變數取值列表 do 指令 done 第二種for迴圈語句 for exp1 exp2 exp3 do 指令done 範例 for和while迴圈的對比 for迴圈 for i 1 i 3 i do echo i done while迴圈 i 1while ...