Linux下select 系統呼叫

2021-07-26 07:30:54 字數 3147 閱讀 1974

一、select()函式功能

select系統呼叫允許程式同時在多個底層檔案表述符上,等待輸入的到達或輸出的完成。

二、函式意義

乙個伺服器可以同時在多個開啟的套接字等待請求到來的方法而處理多個客戶。(只是具體應用的其中之一)

自己的理解,但凡是程式在執行過程中會遇到阻塞(不到條件發生就不往下執行)的情況,都是很浪費cpu資源的。因為程式占用了cpu的時間,卻在等待乙個事件的發生,幹等著不幹活,但是有了select()函式,就可以用乙個程序同時監視很多個檔案描述符到輸入、輸出、錯誤。select函式返回後,通過fd_isset()函式檢測是哪個檔案描述符狀態發生了變化,在進行相應的操作,從而省去了對這麼檔案描述符的等待操作,提高了cpu的利用率。

三、相關的函式原型

#include

#include

void fd_zero(fd_set *fdset);            將fdset集合清零(初始化)

void fd_clr(int fd, fd_set *fdset);    

清除fd檔案描述符

void fd_set(int fd, fd_set *fdset);    

新增fd檔案描述符

int fd_isset(int fd, fd_set *fdset);    

檢測fd是否為fdset檔案描述符集合中的元素,是返回非0值,否返回0;

其中:資料結構「fd_set」是由開啟的檔案描述符構成的集合。上面的四個函式用來控制這個集合。

#include

#include

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout);

引數:        nfds:要測試的描述符範圍,0~(nfds-1)

返回值:

1.readfds集合中有描述符可讀,writefds集合中有描述符可寫,errorfds集合中有描述符遇到錯誤條件時select將返回1,失敗返回-1;

2.如果三種情況都沒有發生,select將在到達timeout超時時間後,返回0;

3.如果timeout為0,則select將一直阻塞,直到有情況發生。(之前說但凡是阻塞就是浪費cpu資源,但是此處的阻塞,也算是犧牲小我,成就大            我了,因為乙個阻塞同時監控著所有檔案描述符的變化,跟每個描述符都阻塞相比,效率還是高的……)

四、例項

例程1.

[cpp]view plain

copy

print?

#include 

#include 

#include 

#include 

#include 

#include 

#include 

intmain(

void

)    

nread = read(0,buffer,nread);  

buffer[nread] = 0;  

printf("read %d from keyboard: %s"

, nread, buffer);  

}  break

;  }  

}  }  

這個程式讀取鍵盤輸入(標準輸入-檔案描述符為0),超時時間設為2.5s

例程2:

server.c

[cpp]view plain

copy

print?

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

intmain()  

bind(server_sockfd, (struct

sockaddr*)&server_address, server_len);  

listen(server_sockfd, 5);  

fd_zero(&readfds);  

fd_set(server_sockfd, &readfds);  

while

(1)  

for(fd = 0; fd

else

else

}  }  }  

}  }  

client.c

[cpp]view plain

copy

print?

/*  make the necessary includes and set up the variables.  */

#include 

#include 

#include 

#include 

#include 

#include 

#include 

intmain()  

/*  we can now read/write via sockfd.  */

write(sockfd, &ch, 1);  

read(sockfd, &ch, 1);  

printf("char from server = %c\n"

, ch);  

close(sockfd);  

exit(0);  

}  

此程式用select系統呼叫實現了伺服器服務於多客戶,沒有採用多程序。伺服器可以讓select同時檢查 監聽套接字 和 客戶端的連線套接字。一旦select指示有活動發生,我們便可以用fd_isset()函式來遍歷所有可能的檔案描述符,以檢查是哪個發生了活動。

如果是監聽套接字可讀,說明正有乙個客戶嘗試連線,此時可以用accept接受連線請求,而不會阻塞;如果是某個客戶連線套接字準備好,說明這個套接字的客戶有情況需要我們處理,這時呼叫ioctl(),如果返回0,則客戶程序已經結束,關閉該套接字並把它從描述符集合中刪除即可。

linux系統下select和poll的實現機理

1.使用者層應用程式呼叫select 2.核心層呼叫sys select do select 最終呼叫檔案描述符fd對應的struct file型別變數的struct file operations f op的poll函式。poll指向的函式返回當前可否讀寫的資訊。1 如果當前可讀寫,返回讀寫資訊。...

linux系統調優

cpu 資源的調優 調整nice值改變程序優先順序 1.nice 概述 在 linux 系統中,nice 值的範圍從 20 到 19 不同系統的值範圍是不一樣的 正值表示低優先順序,負值表示高優先順序,值為零則表示不會調整該程序的優先順序。具有最高優先順序的程式,其 nice 值最低,所以在 lin...

Linux系統調優

1 selinux 修改selinux配置檔案,vi etc selinux config selinux disabled 必須重啟後生效,但可使用setenforce臨時生效來關閉 setenforce 0 2 lnittab 配置檔案在 etc inittab,centos7後使用syetem...