1. 程式人生 > >Linux下C編程學習1---進程、線程

Linux下C編程學習1---進程、線程

拷貝 工作 擁有 本地 存在 3.1 字節 布局 十個

工作中剛開始接觸Linux,基本上編程練手就從多線程Demo開始。首先由於對於進程、線程這些基本概念進行了簡單的認知。

1.程序的認識

程序:硬盤中的二進制文件

  通常意義上就是我們電腦本地保存的一些文件。比如我電腦上安裝好了一個QQ程序,現在它就躺在我的電腦硬盤中,我沒有去啟動它。這時就叫做一個程序。

2.進程的認識

進程: 加載到內存中的二進制文件 + PCB

  現在我運行QQ,計算機會將程序文件從硬盤加載到系統內存中然後執行。這時QQ進程啟動了,可以查看 任務管理器 中QQ這個進程就存在。

  進程啟動之後,所有的數據都加載到內存中。比如我們Linux編譯生成一個可執行的

  計算機系統啟動了一個進程,那就需要去時時刻刻的管理這個進程,以便於去響應這個進程和進程結束之後的回收工作。

  系統在新建一個進程的時候,會給這個進程分配 資源進程控制塊(PCB)。具體情況如下:

  Linux系統啟動一個進程,會為該進程分配一個 虛擬地址空間

  1) 對於32位系統,尋址指針為4字節,對應的虛擬地址空間為0 ~ 2^32,即 0-4G

  2) 對於64位系統,尋址指針為8字節,對應的虛擬地址空間為0 ~ 2^64,即0-16G

  而 進程控制塊PCB就在虛擬地址空間的內核區中。 技術分享圖片

圖2.1 虛擬地址空間

2.1 虛擬地址和虛擬內存、物理內存的概念

物理內存:【跳轉:參考鏈接1】

  簡單說使用角度,就是你這個計算機插的內存條是多大的,那麽這就是他的物理內存。

  CPU中的概念,物理內存就是CPU的地址線可以直接進行尋址的內存空間大小。

  比如8086只有20根地址線,那麽它的尋址空間就是1MB,我們就說8086能支持1MB的物理內存,即使我們安裝了128M的內存條在板子上,我們也只能說8086擁有1MB的物理內存空間。

  同理,32位的CPU就可以支持最大4GB的物理內存空間了;64位的CPU就可以支持最大16GB的物理內存空間了。所以想給電腦加內存條也不是可以隨便加的。

虛擬內存

  從名字上看,“虛擬”的一塊內存。實際上只是一種內存管理手段。

  以上面的進程創建時的4G虛擬內存舉例,並不是真的從計算機的物理內存中分配一塊連續的4G內存空間給這個新建的進程使用。如果這樣的話,咱們的32位計算機總共就4G大的物理內存,你要是啟動個幾十個進程不就把計算機的物理內存擠滿了。

事實上,在每個進程創建加載時,內核只是為進程“創建”了虛擬內存的布局,實際上並不立即就把虛擬內存對應位置的程序數據和代碼(比如.text .data段)拷貝到物理內存中,只是建立好虛擬內存和磁盤文件之間的映射(叫做存儲器映射),等到運行到對應的程序時,才會通過缺頁異常,來拷貝數據進入物理內存。

2.2 進程控制塊 PCB

  就像是生了孩子就得一輩子管著他、操心他一樣。那麽問題來了,你肯定是操心自己家的孩子,不會去操心一個陌生的孩子,因為自己孩子肯定自己認識。那麽系統是通過什麽來標誌、識別這個運行中的進程呢?---- 就是 PCB

  內核區的進程控制PCB 會攜帶該進程的一些信息(如:進程狀態、進程標識.......),是系統感知該進程的唯一標識。Linux內核的進程控制塊是 task_struct結構體。【跳轉:參考文章鏈接1】

技術分享圖片

圖1.2 PCB結構體

3. 線程的認識

  線程:是cpu調度的最小單位。

  一個進程啟動之後,可以在這個進程中創建多個新的子線程。然後這個進程就退化成了一個線程(稱:主線程)。這樣該進程在運行時,就是主線程和被創建的多個子線程去輪流爭取CPU的時間片,執行各自線程中的處理動作。所以我們說 線程是cpu調度的最小單位。

3.1 進程和線程的差異

  (1)進程:是資源分配的基本單位。

  前面提到,系統在創建一個進程時會為這個進程分配一定的資源。但是在新建線程時並沒有再為這些個線程再次分配資源。所以新建的多個子線程共用該進程的地址空間。

  (2)進程之間是相互獨立的。而線程間是有資源依賴關系的。

  例如,我們在一個父進程中,新建了多個子進程。在運行時,任何一個進程的終止,不會影響到其他進程。

  在一個主線程中,新建了多個子線程。在運行時,主線程終止,創建的全部子線程被迫終止(因為主線程結束,系統回收了進程資源,這些線程沒有了資源自然無法正常運行)。

Linux下C編程學習1---進程、線程