『壹』 linux下的select函數是幹嘛的
不是用得很好嗎?精確延時功能。
此外,可以用來判斷讀寫操作是否在指定時間內就緒。
『貳』 linux下select用法
貼代碼來看看
『叄』 關於linux select函數fgets函數
操作系統知道文件描述符對應的設備是否可讀,所以實際是由內核提供系統調用來真正實現 select 的。
一般對於通過 fopen 操作的文件,我們沒必要用 select, 首先你要把 FILE * 轉成對應的文件描述符,其次對於標准文件,一般情況下讀和寫是 non-block 的,select主要是用來對那些會block的設備用的。當然你硬要這么用,也沒問題,但是 select 對於這種文件總是會返回可讀的,和緩沖區里是否有內容無關(緩沖區的實現是在用戶空間的,顯然內核不知道其狀態)。因為即使整個文件都被讀入緩沖區,由於此時描述符處於 EOF 狀態, select 仍然會返回可讀。
這里實在是有太多細節。 總之,不建議濫用select,對於標准文件或者單個設備的讀寫,完全沒意義。
『肆』 關於linux下select函數問題
nfds: 需要檢查的文件描述字個數(即檢查到fd_set的第幾位),數值應該比三組fd_set中所含的最大fd值更大,一般設為三組fd_set中所含的最大fd值加1(如在readset, writeset, exceptset中所含最大的fd為5,則nfds=6,因為fd是從0開始的 )。設這個值是為了提高效率,使函數不必檢查fd_set的所有1024位。 否則函數默認會檢查到最大值
至於你那個補充內容,是這樣的 當調用select()時,由內核根據IO狀態修改fe_set的內容,由此來通知執行了select()的進程哪一socket或文件可讀寫。 這個 是系統內核負責管理的,如果fd1或fd2那個一旦有變化,系統內核會修改其內容就通知select的進程了,如果fd1 fd2都可讀 首先肯定有個先後順序,會記錄下來,挨個處理。
『伍』 Linux中select poll和epoll的區別
select,poll實現需要自己不斷輪詢所有fd集合,直到設備就緒,期間可能要睡眠和喚醒多次交替。而epoll其實也需要調用epoll_wait不斷輪詢就緒鏈表,期間也可能多次睡眠和喚醒交替,但是它是設備就緒時,調用回調函數,把就緒fd放入就緒鏈表中,並喚醒在epoll_wait中進入睡眠的進程。雖然都要睡眠和交替,但是select和poll在「醒著」的時候要遍歷整個fd集合,而epoll在「醒著」的時候只要判斷一下就緒鏈表是否為空就行了,這節省了大量的CPU時間。這就是回調機制帶來的性能提升。
select,poll每次調用都要把fd集合從用戶態往內核態拷貝一次,並且要把current往設備等待隊列中掛一次,而epoll只要一次拷貝,而且把current往等待隊列上掛也只掛一次(在epoll_wait的開始,注意這里的等待隊列並不是設備等待隊列,只是一個epoll內部定義的等待隊列)。這也能節省不少的開銷。
『陸』 linux select檢測為啥是監聽套接字
select系統調用的作用就是讓程序在多個文件描述符上進行等待,而套接字也是屬於文件描述符的一種,所以伺服器程序就可以利用select系統調用,在多個套接字上等待客戶端請求,從而達到同時處理多個客戶端的效果,而等待客戶端請求就需要用listen調用對客戶端進行監聽,select調用檢測的當然就是監聽套接字咯。
select系統調用是檢測一個已打開的文件描述符的集合(這個集合是一個fd_set類型的數據結構),伺服器程序需要創建這個集合,創建時需要用listen調用讓套接字處於監聽狀態,只有這樣當有一個新的連接發生時,描述符才會有活動發生,才能夠被檢測到。
『柒』 linux select 怎麼理解
linux select函數詳解
在Linux中,我們可以使用select函數實現I/O埠的復用,傳遞給 select函數的參數會告訴內核:
•我們所關心的文件描述符
•對每個描述符,我們所關心的狀態。(我們是要想從一個文件描述符中讀或者寫,還是關注一個描述符中是否出現異常)
•我們要等待多長時間。(我們可以等待無限長的時間,等待固定的一段時間,或者根本就不等待)
從 select函數返回後,內核告訴我們一下信息:
•對我們的要求已經做好准備的描述符的個數
•對於三種條件哪些描述符已經做好准備.(讀,寫,異常)
有了這些返回信息,我們可以調用合適的I/O函數(通常是 read 或 write),並且這些函數不會再阻塞.
#include <sys/select.h>
int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,struct timeval *timeout);
返回:做好准備的文件描述符的個數,超時為0,錯誤為 -1.
首先我們先看一下最後一個參數。它指明我們要等待的時間:
struct timeval{
long tv_sec; /*秒 */
long tv_usec; /*微秒 */
}
有三種情況:
timeout == NULL 等待無限長的時間。等待可以被一個信號中斷。當有一個描述符做好准備或者是捕獲到一個信號時函數會返回。如果捕獲到一個信號, select函數將返回 -1,並將變數 erro設為 EINTR。
timeout->tv_sec == 0 &&timeout->tv_usec == 0不等待,直接返回。加入描述符集的描述符都會被測試,並且返回滿足要求的描述符的個數。這種方法通過輪詢,無阻塞地獲得了多個文件描述符狀態。
timeout->tv_sec !=0 ||timeout->tv_usec!= 0 等待指定的時間。當有描述符符合條件或者超過超時時間的話,函數返回。在超時時間即將用完但又沒有描述符合條件的話,返回 0。對於第一種情況,等待也會被信號所中斷。
『捌』 誰能告訴我 linux下select函數到底是干什麼用的 貌似我不用它也可以得到我想要的結果啊
select是用來設置超時時間的,其第一個參數本來是一個文件號,假如讀取該文件長時間沒有返回則超時跳出,而這部分代碼將文件號設置為0,說明只是為了控制延時不過看你這部分代碼,明顯只是實現一個比較精確定時的sleep這段代碼之所以這么做,是因為linux本身的sleep函數非常不準(windows也是一樣),在線程較多,cpu任務較重的時候,sleep函數的精確度根本無法達到要求於是你這段代碼使用select來代替sleep更為精準,其精準程度和內核相關,如果內核的滴答頻率決定的,一般是100HZ也有1000hz的(因內核版本不同而不同),也就是說select做多可以精確到10ms,或者1ms,而sleep就做不到於是這段函數最重要的作用就是用高精確的select函數來代替低精確度的sleep函數,實現時間較為精準的延時。可查閱《Linux就該這么學》了解更多Linux介紹。
『玖』 Linux內核中select,poll和epoll的區別
select:
下面是select的函數介面:
int select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
select 函數監視的文件描述符分3類,分別是writefds、readfds、和exceptfds。調用後select函數會阻塞,直到有描述副就緒(有數據 可讀、可寫、或者有except),或者超時(timeout指定等待時間,如果立即返回設為null即可),函數返回。當select函數返回後,可以 通過遍歷fdset,來找到就緒的描述符。
select目前幾乎在所有的平台上支持,其良好跨平台支持也是它的一個優點。select的一 個缺點在於單個進程能夠監視的文件描述符的數量存在最大限制,在Linux上一般為1024,可以通過修改宏定義甚至重新編譯內核的方式提升這一限制,但 是這樣也會造成效率的降低。
poll:
int poll (struct pollfd *fds, unsigned int nfds, int timeout);
不同與select使用三個點陣圖來表示三個fdset的方式,poll使用一個 pollfd的指針實現。
struct pollfd {
int fd; /* file descriptor */
short events; /* requested events to watch */
short revents; /* returned events witnessed */
};
pollfd結構包含了要監視的event和發生的event,不再使用select「參數-值」傳遞的方式。同時,pollfd並沒有最大數量限制(但是數量過大後性能也是會下降)。 和select函數一樣,poll返回後,需要輪詢pollfd來獲取就緒的描述符。
從上面看,select和poll都需要在返回後,通過遍歷文件描述符來獲取已經就緒的socket。事實上,同時連接的大量客戶端在一時刻可能只有很少的處於就緒狀態,因此隨著監視的描述符數量的增長,其效率也會線性下降。
epoll:
epoll的介面如下:
int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
typedef union epoll_data {
void *ptr;
int fd;
__uint32_t u32;
__uint64_t u64;
} epoll_data_t;
struct epoll_event {
__uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);主要是epoll_create,epoll_ctl和epoll_wait三個函數。epoll_create函數創建epoll文件描述符,參數size並不是限制了epoll所能監聽的描述符最大個數,只是對內核初始分配內部數據結構的一個建議。返回是epoll描述符。-1表示創建失敗。epoll_ctl 控制對指定描述符fd執行op操作,event是與fd關聯的監聽事件。op操作有三種:添加EPOLL_CTL_ADD,刪除EPOLL_CTL_DEL,修改EPOLL_CTL_MOD。分別添加、刪除和修改對fd的監聽事件。epoll_wait 等待epfd上的io事件,最多返回maxevents個事件。
在 select/poll中,進程只有在調用一定的方法後,內核才對所有監視的文件描述符進行掃描,而epoll事先通過epoll_ctl()來注冊一 個文件描述符,一旦基於某個文件描述符就緒時,內核會採用類似callback的回調機制,迅速激活這個文件描述符,當進程調用epoll_wait() 時便得到通知。
epoll的優點主要是一下幾個方面:
1. 監視的描述符數量不受限制,它所支持的FD上限是最大可以打開文件的數目,這個數字一般遠大於2048,舉個例子,在1GB內存的機器上大約是10萬左 右,具體數目可以cat /proc/sys/fs/file-max察看,一般來說這個數目和系統內存關系很大。select的最大缺點就是進程打開的fd是有數量限制的。這對 於連接數量比較大的伺服器來說根本不能滿足。雖然也可以選擇多進程的解決方案( Apache就是這樣實現的),不過雖然linux上面創建進程的代價比較小,但仍舊是不可忽視的,加上進程間數據同步遠比不上線程間同步的高效,所以也 不是一種完美的方案。
2. IO的效率不會隨著監視fd的數量的增長而下降。epoll不同於select和poll輪詢的方式,而是通過每個fd定義的回調函數來實現的。只有就緒的fd才會執行回調函數。
3.支持電平觸發和邊沿觸發(只告訴進程哪些文件描述符剛剛變為就緒狀態,它只說一遍,如果我們沒有採取行動,那麼它將不會再次告知,這種方式稱為邊緣觸發)兩種方式,理論上邊緣觸發的性能要更高一些,但是代碼實現相當復雜。
4.mmap加速內核與用戶空間的信息傳遞。epoll是通過內核於用戶空間mmap同一塊內存,避免了無畏的內存拷貝。
『拾』 Linux下select函數文件描述符狀態的問題
當然是在有輸入或者輸出時文件描述符的讀寫狀態改變咯,比如標准輸入的文件描述符是0,如果用select來等待0號文件描述符,那麼當在鍵盤上敲字元時開始,就是文件描述符的讀寫狀態改變之時,這時select函數就會返回;對於套接字描述符來說也是這樣,用select來等待一個伺服器描述符,那麼當有新的連接請求時(伺服器描述符等待請求時是一個讀描述符,當有新請求時實際上是有一個輸入),伺服器描述符的讀寫狀態改變,select函數返回。順便說一下,檢查哪個文件描述符發生改變,可以用FD_ISSET宏來進行檢測。