1、從Hello World提及緩存
#include<stdio.h> int main() { printf("Hello world\n"); return 0; }
一、程序爲何要被編譯器編譯了以後才能夠運行?安全
二、編譯器在把C語言程序轉換成能夠執行的機器碼的過程當中作了什麼?怎麼作的?多線程
三、最後編譯出來的可執行文件裏面是什麼?除了機器碼還有什麼?他們怎麼存放的,怎麼組織的?併發
四、#include<stdio.h>是什麼意思?把stdio.h包含進來是意味這什麼?C語言庫又是什麼?他怎麼實現的?函數
五、不一樣的編譯器和不一樣的硬件平臺以及不一樣的操做系統,最終編譯出來的結果同樣嗎?爲何?spa
六、Hello World程序是怎麼運行起來的?操做系統是怎麼裝載它的?它從哪兒開始執行,到哪兒結束?main函數以前發生了什麼?main函數結束之後又發生了什麼?操作系統
七、若是沒有操做系統,Hello World能夠運行嗎?若是要在一臺沒有操做系統的機器上運行Hello World須要什麼?應該怎麼實現?線程
八、printf是怎麼實現的?他爲何能夠有不定數量的參數?爲何他可以在終端上輸出字符串?指針
九、Hello World程序運行時,他在內存中是什麼樣子?code
2、萬變不離其蹤
一、北橋芯片主要協調CPU、內存和高速的圖形設備;南橋芯片主要協磁盤、USB等低速設備
二、對稱多處理器(SMP:Symmetrical Multi-Processing):簡單地講就是每一個CPU在系統中所處的地位和所發揮的功能都是同樣的,是相互對稱的。
三、多核處理器(Multi-Core Processer):將多個處理器合併在一塊兒打包出售,這些被打包的處理器之間共享比較昂貴的緩存部件,只保留多個核心,能夠視做SMP簡化版。
四、操做系統做用:CPU調度(多道程序-->分時系統-->多任務系統);設備驅動;內存管理(直接使用物理內存-->分段-->分頁)
3、線程基礎
線程(Thread),有時被稱爲輕量級進程(Lightweight Process, LWP)是程序執行流的最小單元。一個標準的線程是由線程ID、當前指令指針(PC)、寄存器集合和堆棧組成。一般意義上,一個進程是由一個到多個線程組成,各個線程之間共享程序的內存空間(包括代碼段、數據段、堆等)及一些進程級的資源(如打開文件和信號)。
一、多線程使用場景:a、某個操做可能會陷入長時間等候;b、某個操做是CPU密集型;c、程序邏輯是併發(下載);d、相比多進程,多線程共享效率更高
二、線程的私有空間:a、棧;b、線程局部存儲;c、寄存器
三、線程的共享空間:a、全局變量;b、堆上的數據;c、函數裏的靜態變量;d、程序代碼,任何線程都有權限讀取並執行任何代碼;e、打開的文件等資源
四、原子操做:單指令的操做稱之爲原子操做,由於不管如何,單條指令的執行都不會被打斷。爲了不出錯,不少體系結構都提供了一些經常使用的原子指令。
4、線程安全
爲了不多個線程同時讀寫同一個數據而產生不可預料的後果,咱們要將各個線程對同一個數據的訪問同步(Synchronization)。所謂同步,即指在一個線程訪問數據未結束的時候,其餘線程不得對同一個數據進行訪問。
經常使用的線程同步方式:a、二元信號量(Binay Semaphore)/信號量(Semaphore);b、互斥量(Mutex);c、臨界區(Critical Section);d、讀寫鎖(Read-Write Lock);e、條件變量(Condition Variable)。
可重入函數必須知足幾個特色:a、不使用任何靜態或局部的非const變量;b、不返回任何靜態或全局的非const變量的指針;c、僅依賴與調用方提供的參數;d、不依賴任何單個資源的鎖;e、不調用任何不可重入的函數。
5、Double-Check
volatile T*pInst = 0; T* GetInstance() { if(pInst == NULL) { lock(); if(pInst == NULL) { pInst = new T; } unlock(); } return pInst; }
上面的代碼不是線程安全的,緣由有二:一、編譯亂序;二、CPU執行亂序