小小書童記錄select

小記:

阻塞,非阻塞:進(jìn)程/線程要訪問的數(shù)據(jù)是否就緒椰于,進(jìn)程/線程是否需要等待勤婚;
同步呛伴,異步:訪問數(shù)據(jù)的方式褥民,同步需要主動讀寫數(shù)據(jù)季春,在讀寫數(shù)據(jù)的過程中還是會阻塞;異步只需要I/O操作完成的通知消返,并不主動讀寫數(shù)據(jù)载弄,由操作系統(tǒng)內(nèi)核完成數(shù)據(jù)的讀寫。

Select IO復(fù)用模型是上個(gè)世紀(jì)90年代的東西侦副,受限于當(dāng)時(shí)的計(jì)算機(jī)硬軟件的限制,這種技術(shù)隨著epoll的出現(xiàn)逐漸被取代驼鞭,但它畢竟風(fēng)光過秦驯。了解歷史才能更好的展望未來,每一個(gè)有情懷的碼農(nóng)都不應(yīng)該一味抬頭看遠(yuǎn)方挣棕,時(shí)而低頭凝視大地译隘,不亦樂乎~

了解select之前,我們需要了解下位圖(bitmap)洛心,bitmap其實(shí)就是將對象映射到具體的一個(gè)bit位上來固耘,表示對象存在或者被標(biāo)記。bitmap算法有節(jié)省內(nèi)存和快速查詢等特點(diǎn)词身,所以適合處理海量數(shù)據(jù)的排序和查詢厅目。這種古老而牛逼的技術(shù)在數(shù)據(jù)庫,操作系統(tǒng)上都有很廣泛的應(yīng)用。好的损敷,下面引入select中使用到bitmap算法的幾個(gè)API函數(shù)葫笼,也是在使用select這種IO復(fù)用技術(shù)時(shí)經(jīng)常使用到的。

int FD_ZERO(fd_set *fdset);    // 復(fù)位
int FD_CLR(int fd, fd_set *fdset);   // 清零
int FD_SET(int fd, fd_set *fd_set);   // 設(shè)置
int FD_ISSET(int fd, fd_set *fdset);  // 測試設(shè)置

這幾個(gè)函數(shù)主要完成具體 fdfd_set rset 映射關(guān)系的處理拗馒÷沸牵看下fd_set的存儲結(jié)構(gòu):

#ifndef FD_SETSIZE
#define FD_SETSIZE  1024
#endif

#define NBBY    8       /* number of bits in a byte */
typedef long    fd_mask;
#define NFDBITS (sizeof (fd_mask) * NBBY)   /* bits per mask */
#define howmany(x,y)    (((x)+((y)-1))/(y))

typedef struct _types_fd_set {
    fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
} _types_fd_set;

清楚的看到,一個(gè)long類型8個(gè)字節(jié)诱桂,這樣fds_bits就有1024/64 = 16 即16個(gè)64bit的數(shù)組洋丐,每一個(gè)數(shù)組64bit。設(shè)置和清零這兩個(gè)操作是位操作挥等,很方便友绝,自己寫了一個(gè)BitMapGolang代碼,這里也順便貼出:

func (b *BitSet) Set(i uint) {
        ....
    b.set[i>>6] = b.set[i>>6] | (1 << (i & (64 - 1)))
}
func (b *BitSet) Clear(i uint) {
    ....
    b.set[i>>6] &^= 1 << (i & (64 - 1))
}

好了触菜,知道fdset的存儲結(jié)構(gòu)和簡單設(shè)置之后九榔,可以看下selectIO模型中的另外一個(gè)API:

int select(int maxfdp, fd_set *readset, fd_set *writeset, fd_set *exceptset,struct timeval *timeout);

其中有兩個(gè)參數(shù)需要說明下:

  1. 第一個(gè)參數(shù)是timeout, 它代表select超時(shí)時(shí)間。該值有三種狀態(tài):timeout == NULL 無條件等待涡相。 select函數(shù)將返回 -1, erro設(shè)為 EINTR哲泊,表示被迫中斷。timeout->tv_sec == 0 &&timeout->tv_usec == 0 不等待催蝗,直接返回切威。timeout->tv_sec != 0 || timeout->tv_usec != 0 等待指定的時(shí)間,select返回0表示在規(guī)定時(shí)間內(nèi)沒有fd讀寫或者異常事件發(fā)生丙号。
struct timeval  {
        long tv_sec;   /*秒 */
        long tv_usec;  /*微秒 */   
}
  1. 第二個(gè)參數(shù) maxfdp先朦,這個(gè)是文件描述符fd的最大值加1。每次調(diào)用select之前都需要算出最大的fd犬缨,作為maxfd喳魏。

關(guān)于select的內(nèi)核實(shí)現(xiàn)部分,網(wǎng)上有很多文章進(jìn)行了詳細(xì)的描述怀薛,這里就不再贅述刺彩。好的,這里還是不落俗套地提下select的缺點(diǎn):<1> 描述符(FD)數(shù)量問題 枝恋。<2> IO效率隨FD的增加而線性下降创倔。select隨FD的增加性能下降的問題, 在使用方式上可以感受到:用戶態(tài)需要每次select之前復(fù)位所有fd,然后select之后還得遍歷所有fd找到可讀寫或異常的fd焚碌。但至今沒有對select做過benchmark畦攘。

這里隨便帶上poll小弟:

int poll (struct pollfd *fds, unsigned int nfds, int timeout);

其中pollfd的數(shù)據(jù)結(jié)構(gòu):

struct pollfd {
    int fd; /* file descriptor */
    short events; /* requested events to watch */
    short revents; /* returned events witnessed */
};

poll方式并沒有采用selectfdset方式,而是每一個(gè)fd都有一個(gè)自己的pollfd數(shù)據(jù)結(jié)構(gòu)十电,里面存放除了fd外知押,還存放events事件類型叹螟,這樣poll就沒有fd個(gè)數(shù)的上限問題了,但它仍然需要遍歷fds拿到可讀寫或異常的fd朗徊。這點(diǎn)跟select還是一樣的首妖。

好了,小小書童簡單記錄下爷恳,end~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末有缆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子温亲,更是在濱河造成了極大的恐慌棚壁,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件栈虚,死亡現(xiàn)場離奇詭異袖外,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)魂务,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進(jìn)店門曼验,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人粘姜,你說我怎么就攤上這事鬓照。” “怎么了孤紧?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵豺裆,是天一觀的道長。 經(jīng)常有香客問我号显,道長臭猜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任押蚤,我火速辦了婚禮蔑歌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘揽碘。我一直安慰自己次屠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布钾菊。 她就那樣靜靜地躺著帅矗,像睡著了一般偎肃。 火紅的嫁衣襯著肌膚如雪煞烫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天累颂,我揣著相機(jī)與錄音滞详,去河邊找鬼凛俱。 笑死,一個(gè)胖子當(dāng)著我的面吹牛料饥,可吹牛的內(nèi)容都是我干的蒲犬。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼岸啡,長吁一口氣:“原來是場噩夢啊……” “哼原叮!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起巡蘸,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤奋隶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后悦荒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體唯欣,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年搬味,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了境氢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,646評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡碰纬,死狀恐怖萍聊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情嘀趟,我是刑警寧澤脐区,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站她按,受9級特大地震影響牛隅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜酌泰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一媒佣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧陵刹,春花似錦默伍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至羡宙,卻和暖如春狸剃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背狗热。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工钞馁, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留虑省,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓僧凰,卻偏偏與公主長得像探颈,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子训措,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 一伪节、概述 I/O復(fù)用使得程序能同時(shí)監(jiān)聽多個(gè)文件描述符,這對提高程序的性能至關(guān)重要绩鸣。 I/O復(fù)用雖然能同時(shí)監(jiān)聽多個(gè)文...
    saviochen閱讀 1,046評論 0 4
  • 2016-03-06 流ioctl操作 之前提到過ioctl函數(shù)架馋,它能做其他io函數(shù)不能處理的事情。流系統(tǒng)中繼續(xù)采...
    千里山南閱讀 655評論 0 0
  • 本文摘抄自linux基礎(chǔ)編程 IO概念 Linux的內(nèi)核將所有外部設(shè)備都可以看做一個(gè)文件來操作全闷。那么我們對與外部設(shè)...
    lintong閱讀 1,571評論 0 4
  • 串口操作 串口操作需要的頭文件 #include /*標(biāo)準(zhǔn)輸入輸出定義*/ #include /*標(biāo)準(zhǔn)函數(shù)庫定...
    旅行家John閱讀 1,297評論 0 3
  • 一個(gè)工作日的下午,至少對別人而言是工作日局服。一個(gè)人躺在沙發(fā)上钓瞭,心里突然空落落的。 我是沐小熙淫奔,剛從電話銷售公司離職山涡。...
    沐小熙閱讀 284評論 0 0