最近在折騰服務器框架相關問題,學了東西不記下來很快會忘記……html
OS的I/O流程是這樣的:python
在這個從CPU發出調用到收到完成標誌的過程當中就存在一個時間差,如今就有了兩個重要的概念:完成標誌與時間差。服務器
因此有這樣的定義:多線程
I/O控制方式有哪幾種?
1)阻塞I/O(blocking I/O)
2)非阻塞I/O (nonblocking I/O)--> 輪詢
3) I/O複用(select 和poll) (I/O multiplexing)
4)信號驅動I/O (signal driven I/O (SIGIO))
5)異步I/O (asynchronous I/O (the POSIX aio_functions)) --> 回調
看圖便於理解:
出自:Linux的五種I/O模式併發
下面咱們談談服務器,服務器模型也能夠基於異步、同步、阻塞、非阻塞這四個概念框架
須要注意的是對於高併發的程序每每採用「同步非阻塞」而不是「多線程的同步阻塞」,在合理設計任務調度的不一樣階段可以使得併發數遠大於並行數,須要注意的是在高併發情況下爲每一個任務建立一個線程的開銷很大,因此並不採用多線程的同步阻塞。異步
併發:同時進行的任務數量
並行:可同時工做的物理資源(CPU核數等等)async
另外,有個概念是異步IO,其主要是說在同一線程中當遭遇IO時,並不等待而是執行下面的操做直到IO操做完成後再切回當前,其實就是同步非阻塞,在廖雪峯老師的博客中提到這樣一個模型:
異步IO模型須要一個消息循環,在消息循環中,主線程不斷地重複「讀取消息-處理消息」這一過程:高併發
loop = get_event_loop() while True: event = loop.get_event() process_event(event)
消息模型其實早在應用在桌面應用程序中了。一個GUI程序的主線程就負責不停地讀取消息並處理消息。全部的鍵盤、鼠標等消息都被髮送到GUI程序的消息隊列中,而後由GUI程序的主線程處理。oop
因爲GUI線程處理鍵盤、鼠標等消息的速度很是快,因此用戶感受不到延遲。某些時候,GUI線程在一個消息處理的過程當中遇到問題致使一次消息處理時間過長,此時,用戶會感受到整個GUI程序中止響應了,敲鍵盤、點鼠標都沒有反應。這種狀況說明在消息模型中,處理一個消息必須很是迅速,不然,主線程將沒法及時處理消息隊列中的其餘消息,致使程序看上去中止響應。
消息模型是如何解決同步IO必須等待IO操做這一問題的呢?當遇到IO操做時,代碼只負責發出IO請求,不等待IO結果,而後直接結束本輪消息處理,進入下一輪消息處理過程。當IO操做完成後,將收到一條「IO完成」的消息,處理該消息時就能夠直接獲取IO操做結果。
在「發出IO請求」到收到「IO完成」的這段時間裏,同步IO模型下,主線程只能掛起,但異步IO模型下,主線程並無休息,而是在消息循環中繼續處理其餘消息。這樣,在異步IO模型下,一個線程就能夠同時處理多個IO請求,而且沒有切換線程的操做。對於大多數IO密集型的應用程序,使用異步IO將大大提高系統的多任務處理能力。