系統IO模型

web服務器

一、系統IO模型

1.一、消息通訊機制

一、同步和異步
  同步:進程發出請求調用後,進程會一直處於等待狀態,直到內核返回響應消息之後才能進行下一步操做,若是內核一直不返回數據,那麼進程就會一直等待內核響應消息。
  異步:進程發出請求調用後,進程無需等待內核返回響應消息,會進行其餘的操做或者發送下一個調用請求。
  阻塞:IO操做須要完全完成後才返回到用戶空間,調用結果返回以前,調用者被掛起,沒法進行其餘操做,調用者只有在獲得結果以後纔會返回,該線程在此過程當中不能進行其餘處理。
  非阻塞:IO操做被調用後當即返回給用戶一個狀態,無需等到IO操做完全完成,最終的調用結果返回以前,調用者不會被掛起,能夠去作別的事情。
nginx

1.二、同步阻塞型IO

  阻塞IO模型是最簡單的IO模型,用戶線程在內核進行IO操做師被阻塞,用戶線程經過系統調用read發起IO操做,由用戶空間轉到內核空間。內核等到數據包到達後,而後將接收的數據cp到用戶空間,完成read操做,用戶空間須要等待read將數據讀取到buffer後,才繼續處理接受的數據。整個IO請求的過程當中,用戶線程是被阻塞的,這致使用戶在發起IO請求時,不能作任何事情,對CPU的資源利用率不夠。
  優勢:程序簡單,在阻塞等待數據期間進程/線程掛起,基本不會佔用CPU資源
  缺點:每一個鏈接須要獨立的進程/線程單獨處理,這樣雖然能夠有效的利用CPU資源,可是代價就是多進程的大量內存開銷。
  同步阻塞:程序向內核發送IO請求後一直等待內核響應,若是內核處理請求的IO操做不能當即返回,則進程將一直等待並再也不接收新的請求,並由進程輪詢查看IO是否完成,完成後進程將IO結果返回給Client,在IO沒有返回期間進程不能接收其餘用戶的請求,並且只有進程本身去查看IO是否完成。
web

 1.三、同步非阻塞IO

  在同步阻塞IO中,進程實際等待的時間可能包含兩部分,一個是等待數據的就緒,另外一個是等待數據的複製;與此不一樣的是,同步非阻塞IO的調用不會等待數據的就緒,若是數據不可讀或者不可寫,它會當即告訴進程。相比於阻塞IO,非阻塞IO結合反覆輪詢來嘗試數據是否就緒,防止進程被阻塞,最大的好處便在於能夠在一個進程裏同時處理多個IO操做。因爲須要進程執行屢次的輪詢來查看數據是否就緒,這樣花費了大量的CPU時間,使得進程處於忙碌等待狀態。數組

 1.四、多路IO複用

  在實際應用中,特別是在web服務器,同時處理大量的文件描述符是必不可少的(高併發),這時使用同步非阻塞IO顯然不是合理的;由於服務器想要同時接受多個TCP鏈接的數據,就必須輪流對每一個socket調用接收數據的 方法。無論這些socket有沒有能夠接收的數據,都要詢問一遍,那麼假如大部分socket並無數據能夠接收,那麼就會浪費不少CPU時間用於檢查這些socket。多路IO複用就緒通知,就提供了對大量文件描述符就緒檢查的高性能方案,它容許進程經過一種方法同時監聽全部的文件描述符,並能夠快速得到全部就緒的文件描述符,而後只針對這些描述符進行數據訪問。服務器

  select模型:select模型經過一個select()系統調用來監視包含多個文件描述符的數組,當select()返回後,該數組中就緒的文件描述符便會被內核修改標誌位,使得進程能夠得到這些文件描述符從而進行讀寫操做。select的一個缺點是單個進程可以監聽的文件描述符的數量存在最大限制(Linux上通常爲1024),因此加入使用select的服務器最多隻能同時監聽1024(64位操做系統默認爲2048)個鏈接。因爲nginx的prefork模型其底層所使用的的是select模型,所以nginx的prefork的最大鏈接數爲1024。其次,select()所維護的存儲大量文件描述符的數據結構,隨着文件描述符數量的增大,其複製的開銷也線性增加;因爲網絡響應時間的延遲使得大量的TCP鏈接處於非活躍狀態,但調用select()會對全部socket進行一次線性掃描,因此在必定程度上浪費CPU時間。網絡

相關文章
相關標籤/搜索