原文出自: "http://blog.csdn.net/xiaohui_hubei/article/details/16319249" 一、雙緩衝作用 雙緩衝甚至是多緩衝,在許多情況下都很有用。一般需要使用雙緩衝區的地方都是由於“生產者”和“消費者”供需不一致所造成的。這樣的情況在很多地方後可能會發 ...
原文出自:http://blog.csdn.net/xiaohui_hubei/article/details/16319249
一、雙緩衝作用
雙緩衝甚至是多緩衝,在許多情況下都很有用。一般需要使用雙緩衝區的地方都是由於“生產者”和“消費者”供需不一致所造成的。這樣的情況在很多地方後可能會發生,使用多緩衝可以很好的解決。我舉幾個常見的例子:
例 1. 在網路傳輸過程中數據的接收,有時可能數據來的太快來不及接收導致數據丟失。這是由於“發送者”和“接收者”速度不一致所致,在他們之間安排一個或多個緩衝區來存放來不及接收的數據,讓速度較慢的“接收者”可以慢慢地取完數據不至於丟失。
例2. 再如,電腦中的三級緩存結構:外存(硬碟)、記憶體、高速緩存(介於CPU和記憶體之間,可能由多級)。從左到右他們的存儲容量不斷減小,但速度不斷提升,當然價格也是越來越貴。作為“生產者”的 CPU 處理速度很快,而記憶體存取速度相對CPU較慢,如果直接在記憶體中存取數據,他們的速度不一致會導致 CPU 能力下降。因此在他們之間又增加的高速緩存來作為緩衝區平衡二者速度上的差異。
例3. 在圖形圖像顯示過程中,電腦從顯示緩衝區取數據然後顯示,很多圖形的操作都很複雜需要大量的計算,很難訪問一次顯示緩衝區就能寫入待顯示的完整圖形數據,通常需要多次訪問顯示緩衝區,每次訪問時寫入最新計算的圖形數據。而這樣造成的後果是一個需要複雜計算的圖形,你看到的效果可能是一部分一部分地顯示出來的,造成很大的閃爍不連貫。而使用雙緩衝,可以使你先將計算的中間結果存放在另一個緩衝區中,但全部的計算結束,該緩衝區已經存儲了完整的圖形之後,再將該緩衝區的圖形數據一次性複製到顯示緩衝區。
例1 中使用雙緩衝是為了防止數據丟失,例2 中使用雙緩衝是為了提高 CPU 的處理效率,而例3使用雙緩衝是為了防止顯示圖形時的閃爍延遲等不良體驗。
二、雙緩衝原理
這裡,主要以雙緩衝在圖形圖像顯示中的應用做說明。
上面例3中提到了雙緩衝的主要原理,這裡通過一個圖再次理解一下:
註意,顯示緩衝區是和顯示器一起的,顯示器只負責從顯示緩衝區取數據顯示。我們通常所說的在顯示器上畫一條直線,其實就是往該顯示緩衝區中寫入數據。顯示器通過不斷的刷新(從顯示緩衝區取數據),從而使顯示緩衝區中數據的改變及時的反映到顯示器上。
這也是顯示覆雜圖形時造成閃爍的原因,比如你現在要顯示從屏幕中心向外發射的一簇射線,你開始編寫代碼用一個迴圈從0度開始到360度,每隔一定角度畫一條從圓心開始向外的直線。你每次畫線其實是往顯示緩衝區寫入數據,如果你還沒有畫完,顯示器就從顯示緩衝區取數據顯示圖形,此時你看到的是一個不完整的圖形,然後你繼續畫線,等到顯示器再次取顯示緩衝區數據顯示時,圖形比上次完整了一些,依次下去直到顯示完整的圖形。你看到圖形不是一次性完整地顯示出來,而是每次顯示一部分,從而造成閃爍。
原理懂了,看下 demo 就知道怎麼用了。下麵先介紹 Win32 API 和 C# 中如何使用雙緩衝,其他環境下由於沒有用到所以沒寫,等用到了再在下麵補充,不過其他環境下過程也基本相似。