網路IO模型之select基礎
思考:為什麼執行緒開銷會大
一、IO 有兩種操作,同步 IO 和非同步 IO 。
同步 IO 指的是,必須等待 IO 操作完成後,控制權
才返回給使用者程序 。
非同步 IO 指的是,無須等待 IO 操作完成,就將控制權返回給使用者程序。
網路中的 IO ,由於不同的 IO 裝置有著不同的特點,網路通訊中往往需要等待 。 常見的
有以下 4 種情況 。
(1)、輸入操作
(2)、輸出操作
(3)、伺服器接收連線請求
(4)、客戶端傳送連線請求
2、四種網路IO模型
阻塞是指 IO 操作需要徹底完成後才返回到使用者空間;
而非阻塞是指 IO 操作被呼叫後立即返回給使用者一個狀態值,
不需要等到 IO 操作徹底完成
(1)、阻塞IO模型
只有系統呼叫獲得結果或者超時出錯才返回結果
(2)、非阻塞IO模型
從使用者程序角度講,它發起一個 read操作後,並不需要等待,而是馬上就得到了
一個結果 。 當用戶程序判斷結果是一個錯誤時,它就知道資料還沒有準備好,於是它可以
再次傳送 read 操作,在非阻塞式 IO 中,使用者程序其實需要不斷地主動詢問kernel 資料是
否準備好。非阻塞的介面相比於阻塞型介面的顯著差異在於被呼叫之後立即返回 。
使用如下的函式可以將某控制代碼歸設為非阻塞狀態 :fcntl( fd , F_SETFL , O_NONBLOCK );
缺點;迴圈呼叫recv()會很消耗CPU
(3)、多路複用IO
基本原理:就是有個函式(如select)會不斷地輪詢所負責的所有 socket,當某個
socket 有資料到達了,就通知使用者程序,
(4)、非同步IO模型(後面具體來說)
三、select
1、函式原型
#include <sys/select.h>
int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,struct timeval *timeout);
maxfdp 一個整數值,指的是集合中所有檔案描述符的範圍,即檔案描述符數量+1
readfds,writefds,errorfds 都應該包括檔案描述符
timeout 超時時間
2、重要的巨集
void FD_ZERO(int fd, fd_set *fdset); // 關閉描述字集上的所有位
void FD_SET(int fd, fd_set *fd_set);// 開啟描述字集上一個描述符位
void FD_CLR(int fd, fd_set *fdset); // 關閉描述字集上一個描述符位
int FD_ISSET(int fd, fd_set *fdset); // 判斷描述符位是否在描述字集上
(1) FD_ZERO巨集,初始化,將一個 fd_set型別變數的所有位都設為 0