理解select函數(shù)并實(shí)現(xiàn)服務(wù)器端
select函數(shù)調(diào)用過程:
步驟1
----------------
| 設(shè)置文件描述符 |
| 指定監(jiān)視范圍 |
| 設(shè)置超時 |
----------------
↓
步驟2
----------------
| 調(diào)用select函數(shù) |
----------------
↓
步驟3
----------------
| 查看調(diào)用結(jié)果 |
----------------
#include <sys/select.h>
#include <sys/time.h>
/*
* @params
* maxfd: 監(jiān)視對象文件描述符數(shù)量
* readset: 將所有關(guān)注”是否存在待讀取數(shù)據(jù)“的文件描述符注冊到fd_set型變量,并傳遞其地址值
* writeset: 將所有關(guān)注”是否可傳輸無阻塞數(shù)據(jù)“的文件描述符注冊到fd_set型變量,并傳遞其地址值
* exceptset: 將所有關(guān)注”是否發(fā)生異?!暗奈募枋龇缘絝d_set型變量,并傳遞其地址值
* timeout: select函數(shù)是阻塞的,為防止陷入無限阻塞狀態(tài),傳遞超時信息
*/
int select(int maxfd, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timeval *timeout); // 成功時返回發(fā)生關(guān)注事件的fd的個數(shù)(大于0),失敗時返回-1,超時返回0
select函數(shù)調(diào)用完成后,fd_set變量會發(fā)生變化,除發(fā)生變化的文件描述符對應(yīng)位不變,其余位均變?yōu)?。
示例:
# gcc select.c -o select
# ./select
Time out!
Time out!
Hi~
Message feom console: Hi~
應(yīng)用到回聲服務(wù)器中(客戶端可以直接用第十一章的):
# gcc echo_selectserv.c -o selserv
# ./selserv 9190
Time out!
Time out!
Time out!
Connected client: 4
Time out!
Time out!
Connected client: 5
Time out!
Closed client: 4
Closed client: 5
# gcc echo_client.c -o eclient
# ./eclient 127.0.0.1 9190
Connected
Input message (Q to quit): first
Message from server: first
Input message (Q to quit): bye
Message from server: bye
Input message (Q to quit): q
# ./eclient 127.0.0.1 9190
Connected
Input message (Q to quit): second
Message from server: second
Input message (Q to quit): qingtian
Message from server: qingtian
Input message (Q to quit): Q
習(xí)題
- 請解釋復(fù)用技術(shù)的通用含義,并說明何為I/O復(fù)用。
復(fù)用技術(shù)是為了提高物理設(shè)備的效率,用最少的物理要素傳遞最多數(shù)據(jù)時使用的技術(shù)。I/O復(fù)用是通過一個進(jìn)程向多個客戶端提供服務(wù)。- 多進(jìn)程并發(fā)服務(wù)器的缺點(diǎn)有哪些?如何在I/O復(fù)用服務(wù)器端中彌補(bǔ)?
每個進(jìn)程都占用一份內(nèi)存,數(shù)據(jù)交換也較復(fù)雜。I/O復(fù)用服務(wù)器通過一個進(jìn)程向多個客戶端提供服務(wù),避免了這些問題。- 復(fù)用服務(wù)器端需要select函數(shù)。下列關(guān)于select函數(shù)使用方法的描述錯誤的是?
a. 調(diào)用select函數(shù)前需要集中I/O監(jiān)視對象的文件描述符。
b. 若已通過select函數(shù)注冊為監(jiān)視對象,則后續(xù)調(diào)用select函數(shù)時無需重復(fù)注冊。
c. 復(fù)用服務(wù)器端同一時間只能服務(wù)于1個客戶端,因此,需要服務(wù)的客戶端接入服務(wù)器端后只能等待。
d. 與多進(jìn)程服務(wù)器端不通,基于select的復(fù)用服務(wù)器端只需要1 個進(jìn)程。因此,可以減少因創(chuàng)建進(jìn)程產(chǎn)生的服務(wù)器端的負(fù)擔(dān)。
b。- select函數(shù)的觀察對象中應(yīng)包含服務(wù)器端套接字(監(jiān)聽套接字),那么應(yīng)將其包含到哪一類監(jiān)聽對象集合?請說明原因。
“是否存在待讀取數(shù)據(jù)”集合。為什么要加進(jìn)這個集合?
我的問題
- 如果select返回后程序沒有做處理,下一次再調(diào)用select函數(shù),這些事件還在嗎?
附錄
[1] Github