1. 程式人生 > 其它 >幼麟實驗室 協程, 大丙 I/O多路複用

幼麟實驗室 協程, 大丙 I/O多路複用

  • 執行緒是程序中的執行體,協程只有使用者態棧
  • 協程實現了使用者態多工模型
  • 由於現在高併發場景頻繁出現,之前的多程序模型的記憶體資源捉襟見肘
    多程序模型下,核心態與使用者態多次轉換,仍然疲於應對高併發場景
  • socket的所有操作都由os來完成,一個程序每建立一個socket,就會在開啟檔案描述符表中增加一個記錄,返回給應用程式的只有socket描述符,每個TCP socket被建立時,os都會為它建立一個讀緩衝區與一個寫緩衝區要獲得響應資料,就要從讀緩衝區拷貝過來,要通過socket傳送資料,也要把資料拷貝到寫快取區
  • 當執行讀/寫操作的時候,讀/寫緩衝區裡沒有資料,一種方式是執行緒讓出CPU,等到資料就緒且執行緒獲得時間片,就可以繼續執行,這就是阻塞式I/O
    ,就像mutex阻塞式I/O要處理一個socket,就要佔用一個執行緒,一個執行緒處理完一個socket,才能處理下一個,在高併發場景下,會加劇排程開銷
  • 非阻塞式I/O,有點像spinlock,也就是即使緩衝區中沒有資料,也不讓出CPU,而是頻繁的去檢查socket緩衝區是否就緒,這是一種忙等待容易造成空耗CPU,加劇響應延遲
  • I/O多路複用,OS把多個socket加入到監聽集合,這樣就可以通過一次系統呼叫(也就是陷入核心去檢查socket緩衝區)監聽多個socket,有socket就緒了,就可以逐個處理了,這樣就不會為了等待某個socket而阻塞或者是忙等待。linux中有三種I/O多路複用的方式:
    • select
      可以設定要等待的描述符,也可以設定等待超時的時間,如果有準備好的fd或者達到超時時間select函式就會返回,select的函式簽名中的引數表明,其可以監聽讀/寫/異常三類事件,fd_set是一個unigned long型別的陣列一共有16個元素,每個可以儲存64位,也就是一共可以監聽1024個檔案描述符fd,這太少了,而且每次呼叫select都傳遞所有的監聽集合,需要頻繁從使用者態到核心態的資料拷貝,初次之外,即便是存在fd就緒了,也需要遍歷整個監聽集合,這些都很影響效能
      • select跨平臺,可以在W/M/L都可以使用,
    • poll,可以支援的fd數目變多了
    • epoll