日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多路 IO 转接 :select 函数

發(fā)布時(shí)間:2024/9/30 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多路 IO 转接 :select 函数 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

(1)頭文件:

#include <sys/select.h>

(2)函數(shù)原型:

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

(3)參數(shù)說明
1)參數(shù)1:監(jiān)聽的所有文件描述符中,最大文件描述符的編號 + 1(即監(jiān)聽 fd 的總個(gè)數(shù))。
2)參數(shù)2、3、4:監(jiān)聽的文件描述符 “是否可讀”、“是否可寫”、“是否異常” 的事件;fd_set代表文件描述符集合,本質(zhì)是位圖。
3)參數(shù)5:設(shè)定超時(shí)返回結(jié)果,若填 NULL 代表永久阻塞,直至有事件發(fā)生, 若值為0代表立即返回,非阻塞效果。
這里有兩點(diǎn)要注意的地方:
1)是最常監(jiān)聽 readfds;writefds 在 epoll 反應(yīng)堆會使用;exceptfds 一般是內(nèi)核給系統(tǒng)函數(shù)內(nèi)部使用。
2)以參 2 readfds 為例,并不是我監(jiān)聽它可讀,它就一定可讀,因此在設(shè)計(jì)上,都是傳入傳出參數(shù)。傳入體現(xiàn)在告訴內(nèi)核,我想監(jiān)聽誰是否可讀。傳出體現(xiàn)在通過 select 函數(shù)的監(jiān)聽,內(nèi)核告訴我具體結(jié)果,誰是可讀的。如下圖

(4)返回值:
成功返回所監(jiān)聽的滿足條件的文件描述符總數(shù)量。
例如:
監(jiān)聽 r:fd1 fd2 fd3
w:fd1 fd3
err:fd1 fd2
滿足條件 r:fd1 fd3
w:fd1 ; err:fd2
則返回值為4 (不要在意 fd1 是否有重復(fù),因?yàn)樗麄儗儆诓煌录?#xff09;。
失敗:返回 -1,設(shè)置 errno (如果 timeout =0, errno = EAGAIN,代表正常)。
(5)添加監(jiān)聽的文件描述符函數(shù):

void FD_ZERO(fd_set *set); // 將 set 清空 全部置 0 void FD_SET(int fd, fd_set *set); // 將 fd 添加到 set 中清除(0 變 1) void FD_CLR(int fd, fd_set *set); // 將 fd 從 set 中清除 (1 變 0) int FD_ISSET(int fd, fd_set *set); // 判斷 fd 是否在 set 中(返回 1 表明在)

(6)在返回值中確定哪個(gè)文件描述符可讀,哪個(gè)可寫

fd_set readfds; // 定義監(jiān)聽讀事件的文件描述符集合 FD_ZERO(&readfds); // 清空 FD_SET(fd1, &readfds); FD_SET(fd2, &readfds); FD_SET(fd3, &readfds); // 監(jiān)聽 fd1、fd2、fd3 是否可讀 select(); //以上面結(jié)果為例(不考慮 writefds 和 exceptfds)返回值 = 1,但我不知道是誰 //判斷是否在相應(yīng)集合中 int ret = FD_ISSET(fd1, & readfds); // 發(fā)現(xiàn) ret = 1 說明可讀,意味著客戶端向服務(wù)器發(fā)送數(shù)據(jù),可以通過 fd1 讀取數(shù)據(jù) int ret = FD_ISSET(fd2 & readfds); // 顯然 結(jié)果 = 0 int ret = FD_ISSET(fd3, & readfds); // 顯然 結(jié)果 = 0

(7)select 函數(shù)優(yōu)缺點(diǎn)
優(yōu)點(diǎn):一個(gè)線程就可以支持多個(gè)客戶端(多路 IO 都有這個(gè)優(yōu)點(diǎn)),可以跨平臺(select 獨(dú)有)。
缺點(diǎn):
1)同時(shí)監(jiān)聽文件描述符的上限是 1024 個(gè),注意不是因?yàn)榇蜷_文件的上限是 1024(上限數(shù)可以修改),而是因?yàn)樵?select 底層實(shí)現(xiàn)時(shí)候,fd_set使用了宏 FD_SETSIZE = 1024。
2)返回值是一個(gè)數(shù)量,需要循環(huán)遍歷判斷到底誰符合條件,因此高并發(fā)少訪問的時(shí)候,效率低。
3)監(jiān)聽集合和滿足監(jiān)聽條件的集合是同一個(gè)集合,select 后會改變原監(jiān)聽集合,使其無法再次使用,因此,select 前需要將原監(jiān)聽集合保存。
(8)監(jiān)聽事件分類:
需要監(jiān)聽事件分為 2 類,首先一類是建立連接請求(其實(shí)是監(jiān)聽讀事件即服務(wù)器寫給我請求,我來讀),另一類是讀寫事件請求 (這些都是建立連接之后的事)。就是說,最開始需要監(jiān)聽一個(gè)讀描述符,有結(jié)果,意味著有客戶端請求連接,此時(shí)服務(wù)器調(diào)用 accept 函數(shù)便會立即建立連接(雖然 accept 是阻塞函數(shù),但此時(shí)不會有阻塞效果),然后再監(jiān)聽讀寫。

總結(jié)

以上是生活随笔為你收集整理的多路 IO 转接 :select 函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。