select函式中的演算法

2021-08-16 22:49:35 字數 1442 閱讀 1315

先討論與io無關的東西.

呼叫select 的流程是

1 將要監聽的檔案描述符(集)a,b,c選入乙個集合s

2 呼叫select,可以設定超時引數

4 函式內部設定s集合中的描述符

3 函式返回,解析s中還有哪些述符

怎樣高效的來實現上述的過程.我們知道檔案描述符是乙個較小遞增不重複的int,根據這個特點,我們可以用bitmap演算法來實現,本質是乙個對映關係.用幾個較少的數來表示很多的數

首先我們來討論一下怎麼用乙個數來表示多個數.比方數123裡面有三個數字1,2,3.把5,6,7打包成乙個數,即567,很簡單.把56,7打包成乙個數,也是567.是不是懵了.也就是說這種表示是有問題的,解包的時候不確定,而且你也不能把兩個大數打包,這樣會溢位.計算機都是二進位制的世界.我們考慮一下二進位制數.

比如1為1,2為10,4為100,8為1000

我們這麼規定,給定乙個二進位制數(x)第幾(n)位是1就表示包含該數(n)

比如101,我們就知道包含兩個數1,3.

10110就包含三個數2,3,5

1000000只包含乙個數7

1111111111就包含了1,2,3,4,5,6,7,8..

1111111.......包含1,2,3,4,5,6,7........

可以無限發展嗎?要知道計算機裡的數表示是有邊界的

乙個int只有32位,即最多包含32個數.由於32太多,為了書寫起來方便,我們已8位來討論邊界問題

8個1能表示8個數,10000000表示數8.如果要表示數9怎麼辦,沒有辦法了吧.

再回到上面的集合s來,將一些較小的數選入集合,我們都是有辦法來表示的

fd_set(1,&set);

fd_set(2,&set);

...fd_set(8,&set);

fd_set(9,&set); //這裡可能就要溢位了,因為set最多只能有8位了.

我們再借乙個set來表示9可不可以.

即fd_set(1,&set[0]);

fd_set(2,&set[0]);

...fd_set(8,&set[0]);

fd_set(9,&set[1]);

fd_set(10,&set[1]);

看到沒,我們用第乙個set來表示了

我們來正式討論select函式中的檔案描述符集

用盡可能多的1來盛裝乙個數,64位linux中用64位數來表示,也就是說乙個set可以最大表示64個數,要想表示第65個,必須再起乙個set.要想表示1024個數,則有64個set,第乙個set[0]表示[0,63],第二個set[1]表示[64,127]....第16個set[15]表示[960,1023]

fd_set的結構實際上是__fds_bits[n]的陣列n為max/(sizeof(long int)*8) max為1024

為什麼max是1024,這個涉及到效率問題,底層控制太多的檔案描述符也會降低效率.

socket中的select函式使用

分類 windows sdk series 程式語言基礎 2012 07 07 17 14 126人閱讀收藏 舉報socket select 函式用於定時檢查以建立的socket控制代碼的狀態,以確定設定的socket控制代碼當前是否可寫或有資料可讀。select函式提供了一種方法,使得程式在操作s...

TCP中select函式的理解

1 select一般用在非阻塞的通訊中 主要可以設定超時時間 2 一般服務端可以使用select的模型,如建立socket以後,監聽等待直到有accept,3 然後可以對所有接入的連線輪訓進行資料報的收發,主要使用如下幾個函式,該方法跟linux下poll或者epoll相似 fd zero set ...

linux中select函式的使用

linux中select函式的使用 select在socket程式設計中還是比較重要的,可是對於初學socket的人來說都不太愛用select寫程式,他們只是習慣寫諸如connect accept recv或recvfrom這樣的阻塞程式 所謂阻塞方式block,顧名思義,就是程序或是執行緒執行到這...