1.計算機硬件的三個部件最爲重要:中央處理器CPU,內存和IO控制芯片。編程
2.主板上北橋芯片處理高速設備。南橋芯片處理低速設備,而後彙總後鏈接到北橋上。緩存
3.多個處理之間共享比較昂貴的緩衝部件,只保留報個核心,而且以一個處理器的外包裝出售,售價比單核心的處理器只貴了一點,這就是多核處理器(Multi-core Processor)的基本想法。安全
4.操做系統內核層對於硬件層來講是硬件接口的使用者,而硬件是接口的定義者,硬件的接口定義決定了操做系統內核,具體來說就是驅動程序如何操做硬件,如何與硬件進行通訊。這種接口每每被叫作硬件規格(HardWare Specification),硬件的生產廠商負責提供硬件規格,操做系統和驅動程序的開發者經過閱讀硬件規格所規定的各類硬件編程接口標準來編寫操做系統和驅動程序。多線程
5.早期的計算機中,程序是直接運行在物理內存上的,多個程序運行時也都被分配在物理內存上,這樣的分配策略引起了3個重要問題:程序之間的地址空間不隔離,內存使用效率低,程序運行的地址不肯定。解決這幾個問題的思路就是增長中間層,即便用一種間接的地址訪問方法。整個想法是這樣的,咱們把程序給出的地址看做是一種虛擬地址(Virtual Address),而後經過某些映射的方法,將這個虛擬地址轉換成實際的物理地址。這樣,只要咱們可以妥善地控制這個虛擬地址到物理地址的映射過程,就能夠保證任意一個程序所可以訪問的物理內存區域跟另一個程序相互不重疊,以達到地址空間隔離的效果,同時也能夠作到每一個程序的地址是相同的。而內存使用效率低這個問題人,們很天然地想到了更小粒度的內存分割和映射的方法,使得程序的局部性原理獲得充分的利用,大大提升了內存的使用率。這種方法就是分頁(Paging)。併發
6.虛擬存儲的實現須要依靠硬件的支持,對於不一樣的CPU來講是不一樣的,可是幾乎全部的硬件都採用一個叫作MMU(Memory Management Unit)的部件來進行頁映射。通常MMU都集成在CPU內部了,不會以獨立的部件存在。函數
7.線程(Thread),有時被稱爲輕量級進程(Lightweight Process,LWP),是程序執行流的最小單元。一個標準的線程由線程ID、當前指令指針(PC),寄存器集合和堆棧組成。一般意義上,一個進程由一個到多個線程組成。各個線程之間共享程序的內存空間(包括代碼段,數據段,堆等)及一些進程級的資源(如打開文件和信號)。優化
8.通常把頻繁等待的線程稱之爲IO密集型線程(IO Bound Thread),把不多等待的線程成爲CPU密集型線程(CPU Bound Thread)。IO密集型線程老是比CPU密集型線程容易獲得優先級的提高。在線程優先級調度下,存在一種餓死(Starvation)的現象,一個線程被餓死,是說它的優先級較低,在它執行以前,老是有較高優先級的線程試圖執行,所以這個低優先級線程始終沒法執行。當一個CPU密集型的線程得到較高的優先級時,許多低優先級的線程極可能餓死。而一個高優先級的IO密集型線程因爲大部分時間都處於等待狀態,所以相對不容易形成其餘線程餓死。爲了不餓死現象,調度系統經常會逐步提高那些等待了過長時間的得不到執行的線程的優先級。在這樣的手段下,一個線程只要等待足夠長的時間,其優先級必定會提升到足夠讓它執行的程序。操作系統
9.fork產生新任務的速度很是快,由於fork並不複製原任務的內存空間,而是和原任務一塊兒共享一個寫時複製(Copy On Write,COW)的內存空間。所謂寫時複製,指的是兩個任務能夠同時自由地讀取內存,單任意一個任務試圖對內存進行修改時,內存就會複製一份提供給修改方單獨使用,以避免影響到其餘的任務使用。線程
10.互斥量和二元信號量很相似,資源僅同時容許一個線程訪問,但和信號量不一樣的是,信號量在整個系統能夠被任意線程獲取並釋放,也就是說,同一個信號量能夠被系統中的一個線程獲取以後由另外一個線程釋放。而互斥量則要求那個線程獲取了互斥量,哪一個線程就要負責釋放這個鎖,其餘線程越俎代庖去釋放互斥量是無效的。指針
11.臨界區是比互斥量更加嚴格的同步手段。互斥量和信號量在系統的任何進程都是可見的,也就是說,一個進程建立了一個互斥量或信號量,另外一個進程試圖去獲取該鎖是合法的。然而,臨界區的做用範圍僅限於本進程,其餘的進程沒法獲取該鎖,除此以外,臨界區具備和互斥量相同的性質。
12.一個函數要成爲可重入的,必須具備以下幾個特色:
1.不使用任何(局部)靜態或全局的非const變量;
2.不返回任何(局部)靜態或全局的非const變量的指針;
3.僅依賴於調用方提供的參數;
4.不依賴任何單個資源的鎖(mutex等);
5.不調用任何不可重入的函數。
可重入是併發安全的強力保障,一個可重入的函數能夠在多線程環境下放心使用。
13.volatile關鍵字試圖阻止過分優化,volatile基本能夠作到兩件事情:
1.阻止編譯器爲了提升速度將一個變量緩存到寄存器內而不寫回;
2.阻止編譯器調整操做volatile變量的指令順序(即便volatile可以阻止編譯器調整順序,也沒法阻止CPU動態調度換序);
14.CPU的亂序執行能力讓咱們對多線程的安全保障的努力變得異常困難。所以要保證線程安全,阻止CPU換序是必需的。遺憾的是,如今並不存在可移植的阻止換序的方法。一般狀況下是調用CPU提供的一條指令,這條指令經常被稱爲barrier。一條barrier指令會阻止CPU將該指令以前的指令交換到barrier以後,反之亦然。換句話說,barrier指令的做用相似於一個攔水壩,阻止換序「穿透」這個大壩。
關於barrier()宏實際上也是優化屏障:
#define barrier() __asm__ volatile (」lwsync」)
CPU越過內存屏障後,將刷新本身對存儲器的緩衝狀態。這條語句實際上不生成任何代碼,但可以使gcc在barrier()以後刷新寄存器對變量的分配。
1.set_mb(),mb(),barrier()函數追蹤到底,就是__asm__ __volatile__("":::"memory"),而這行代碼就是內存屏障; 2.__asm__用於指示編譯器在此插入彙編語句; 3.__volatile__用於告訴編譯器,嚴禁將此處的彙編語句與其它的語句重組合優化。