【底層原理】用戶進程緩沖區和內核緩沖區


作者:Pulpcode

鏈接:http://www.pulpcode.cn/2017/02/01/user-buffer-and-kernel-buffer/

碼農有道作了部分修改

 

常常聽到有程序員會跟你討論:“我們在讀寫文件的時候,系統是有緩存的”。但實際上有一部分人把用戶進程緩沖區和系統空間的緩沖區的概念混淆了,包括這兩種緩沖區的用法和所要解決的問題,還有其它類似的概念。本文就來區分一下不同的緩沖區概念(主要針對類unix平台)。

 

用戶進程和操作系統的關系

首先我用一張圖來解釋“用戶進程和操作系統的關系”

這是一個計算機系統運行時的簡化模型,我們把所有運行在操作系統上的進程成為用戶進程,它們都運行在用戶空間(可以看到用戶空間有很多進程)。把操作系統運行的空間成為系統空間

為什么將進程分為用戶進程和系統進程,首先你一定聽說過內核態和用戶態(kernel mode和user mode),在內核態可以訪問系統資源,比如:

處理器cpu:cpu控制着一個程序的執行。

輸入輸出IO:linux有句話叫“一切都是流”,也就是所有輸入輸出設備的數據,包括硬盤,內存,終端都可以像流一樣操作。

進程管理:類似對進程的創建,休眠,喚醒,釋放之類的調度。比如linux下的fork和windows下的CreateProcess()函數。

內存:包括內存的申請,釋放等管理操作。

設備:這個就是常常說的外設了,比如鼠標,鍵盤。

計時器:計算機能計時是因為晶體振盪器產生的電磁脈沖。那么所有的定時任務都是以它為基礎的。

進程間通信IPC:進程之間是不能夠互相訪問內存的,所以進程與進程之間的交互需要通信,而通信也是一種資源。

網絡通信:網絡通信可以看做是進程見通信的特殊形式。

而上面所說的這些系統資源,在用戶進程中是無法被直接訪問的,只能通過操作系統來訪問,所以也把操作系統提供的這些功能成為:“系統調用”。

比如下圖,展示一個用戶通過shell控制計算機所經過的數據流向:文件讀寫和終端控制,都是通過內核進行的。

提供這些限制的基礎就是cpu提供的內核態和用戶態。比如intel x86 CPU有四種不同的執行級別0-3,linux只使用了其中的0級和3級分別來表示內核態和用戶態。

在用戶態,不僅僅是系統資源了,就是別的進程的內存對於你來說,都是“透明的”(並不是沒辦法訪問,否則游戲作弊器怎么實現?)

 

 

 

用戶進程緩沖區

前面提到,用戶進程通過系統調用訪問系統資源的時候,需要切換到內核態,而這對應一些特殊的堆棧和內存環境,必須在系統調用前建立好。而在系統調用結束后,cpu會從核心模式切回到用戶模式,而堆棧又必須恢復成用戶進程的上下文。而這種切換就會有大量的耗時。

你看一些程序在讀取文件時,會先申請一塊內存數組,稱為buffer,然后每次調用read,讀取設定字節長度的數據,寫入buffer。(用較小的次數填滿buffer)。之后的程序都是從buffer中獲取數據,當buffer使用完后,在進行下一次調用,填充buffer。

所以說:用戶緩沖區的目的是為了減少系統調用次數,從而降低操作系統在用戶態與核心態切換所耗費的時間

 

 

 

內核緩沖區

除了在進程中設計緩沖區,內核也有自己的緩沖區。

當一個用戶進程要從磁盤讀取數據時,內核一般不直接讀磁盤,而是將內核緩沖區中的數據復制到進程緩沖區中。

但若是內核緩沖區中沒有數據,內核會把對數據塊的請求,加入到請求隊列,然后把進程掛起,為其它進程提供服務。

等到數據已經讀取到內核緩沖區時,把內核緩沖區中的數據讀取到用戶進程中,才會通知進程,當然不同的io模型,在調度和使用內核緩沖區的方式上有所不同,下一小結介紹。

你可以認為,read是把數據從內核緩沖區復制到進程緩沖區。write是把進程緩沖區復制到內核緩沖區。

當然,write並不一定導致內核的寫動作,比如os可能會把內核緩沖區的數據積累到一定量后,再一次寫入。這也就是為什么斷電有時會導致數據丟失。

所以說內核緩沖區,是為了在OS級別,提高磁盤IO效率,優化磁盤寫操作。

 

 

流程

在《Unix網絡編程》中的五種io模型,也提到過進程緩沖區和內核緩沖區。因為這個並不是此篇文章的重點,所以這里只對比阻塞模型和非阻塞。

對比阻塞和非阻塞,在阻塞io中,直到數據從內核緩沖區拷貝到用戶緩沖區才通知用戶進程調用完成並喚醒,而非阻塞,在輪訓得知數據准備好后,數據還是在內核緩沖區中,等你去讀取,這也就是說數據准備好,並不代表已經讀好可以使用。當然也不代表一定能讀。

 

 

緩沖區和緩存

還有一部分人把緩沖區和緩存混淆,后來我明白這也是因為翻譯導致的把兩種東西進行混淆。緩沖區的英文是buffer,而緩存的應為是cache。

 

CPU緩存(Cache Memory)是位於CPU與內存之間的臨時存儲器,因為cpu的計算速度要比內存的讀寫速度快很多,而把這些可能會被重復訪問到的數據存儲於cpu緩存中,就會提高讀取速度。可以說緩存是cpu和內存之間的臨時存儲器。

也就是說,buffer是因為減少調用次數,集中調用,提高系統性能。而cache是將讀取過的數據保存起來,重新讀取時若命中(找到需要的數據)就不要去讀硬盤了,若沒有命中就讀硬盤。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM