一:概述
在網路程式設計中,阻塞、非阻塞、同步、非同步經常被提到,下面談一下i/o在生活中的釣魚場景(純屬虛構,如有雷同,純屬巧合)。
1.阻塞式i/o:開始釣魚,眼睛一直盯著,魚兒上鉤拉桿。
2.非阻塞式i/o:開始釣魚,你一直懷疑魚兒在偷吃魚餌,一直拉桿,沒有魚,然後重複放杆拉桿,直到有釣上魚。
3.i/o復用:開始釣魚,但是你同時放了多條魚竿,然後開始眼睛不斷檢視多條魚竿,直到叼上魚。
4.訊號驅動:開始釣魚,但是你的魚竿很特殊,魚兒上鉤會發出聲音通知你,你可以同時幹別的事。
5.非同步i/o:姜太公釣魚公升級版,魚兒不僅願者上鉤而且還會自己跳到裝魚的容器中,連拉桿都省了。
二:網路io模型
應用程式呼叫乙個io函式,導致應用程式阻塞,等待資料準備好。 如果資料沒有準備好,一直等待資料準備好了,從核心拷貝到使用者空間,io函式返回成功指示。
當系統請求的i/o操作無法完成時,不要將程序/執行緒睡眠,而是返回乙個錯誤。這樣我們的i/o操作函式將不斷的測試資料是否已經準備好,如果沒有準備好,繼續測試,直到資料準備好為止。在這個不斷測試的過程中,會大量的占用cpu的時間。
i/o復用模型會用到select、poll函式,這幾個函式也會使程序阻塞,但是和阻塞i/o所不同的的,這兩個函式可以同時阻塞多個i/o操作。而且可以同時對多個讀操作,多個寫操作的i/o函式進行檢測,直到有資料可讀或可寫時,才真正呼叫i/o操作函式。
首先我們允許套介面進行訊號驅動i/o,並安裝乙個訊號處理函式,程序繼續執行並不阻塞。當資料準備好時,程序會收到乙個sigio訊號,可以在訊號處理函式中呼叫i/o操作函式處理資料。
水平觸發的事件驅動機制;核心通知程序來讀取資料,程序沒來讀取資料,核心需要一次一次的通知程序;
邊緣觸發的事件驅動機制;核心只通知一次讓程序來讀取資料,程序可以在超時時間之內隨時來讀取資料。
nginx就採用了邊緣觸發的事件驅動機制,這就是為什麼nginx的併發性比apache好,當然nginx的效能比apache好,還有其它方面,如nginx支援非同步i/o,mmap(記憶體對映)等等
當乙個非同步過程呼叫發出後,呼叫者不能立刻得到結果。實際處理這個呼叫的部件在完成後,通過狀態、通知和**來通知呼叫者的輸入輸出操作。
五種網路IO模型簡介
linux的socket在預設情況都是阻塞的,當使用者程序請求讀取網路資料的時候,如果資料還沒有到達,程序就會被阻塞,一直等到資料到達,並且資料從kernel拷貝到使用者程序的記憶體後,才會解除阻塞狀態,重新開始執行。當使用者程序請求讀取資料的時候,如果資料還沒準備好,kernel會立即返回乙個er...
五種IO模型
再講io模型之前,給大家舉乙個釣魚的例子。張三去釣魚,他釣魚的時候一動不動,一直看著魚竿,看有沒有動,無論是誰叫他,他都不動,只有等魚梢動了 魚上鉤了 他才會動 李四去釣魚,他沒有像張三那樣瓷楞著,只是時不時的輪詢檢查魚竿有沒有動。一直在動。王五也來釣魚,他就比較聰明了,在魚竿上掛個鈴鐺,只要鈴鐺響...
五種IO模型
阻塞io 在核心將資料準備好之前,系統呼叫會一直等待,所有的套接字都是預設阻塞方式 非阻塞io 如果核心還沒有將資料準備好,系統呼叫會直接返回,並返回錯誤碼 非阻塞io往往需要以迴圈的方式反覆讀寫檔案描述符,這個過程稱為輪詢,對cpu的浪費較大,一般只在特定的場景下使用 訊號驅動io 核心將資料準備...