進程與線程間的聯繫與區別以及通信方式

1.定義

1.1進程

進程(Process)是計算機中的程序關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是操作系統結構的基礎。在早期面向進程設計的計算機結構中,進程是程序的基本執行實體;在當代面向線程設計的計算機結構中,進程是線程的容器。程序是指令、數據及其組織形式的描述,進程是程序的實體。

1.2線程

線程是程序中一個單一的順序控制流程。進程內一個相對獨立的、可調度的執行單元,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位。在單個程序中同時運行多個線程完成不同的工作,稱爲多線程。

2.進程與線程間的聯繫

(1)一個線程只能屬於一個進程,同一個進程可以由多個線程,但至少有一個線程。

(2)資源分配給進程,同一進程的所有線程共享該進程所有資源。

(3)處理機分給線程,即真正在處理機上運行的是線程。

(4)線程在執行過程中,需協作同步,不同進程的線程間要利用消息通信的辦法實現同步。

3.進程與線程間的區別

進程和線程的主要差別在於它們是不同的操作系統資源管理方式。進程有獨立的地址空間,一個進程崩潰後,在保護模式下不會對其它進程產生影響,而線程只是一個進程中的不同執行路徑。線程有自己的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等於整個進程死掉,所以多進程的程序要比多線程的程序健壯,但在進程切換時,耗費資源較大,效率要差一些。但對於一些要求同時進行並且又要共享某些變量的併發操作,只能用線程,不能用進程。

 

 

詳細補充一些

1.定義

【進程】是具有一定獨立功能的程序關於某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位.每一個進程都有一個自己的地址空間,即進程空間或(虛空間)。大小隻與處理機的位數有關,一16位處理機的空間大小爲216 ,而 32 位處理機的進程空間大小爲 232 。進程至少有 5 種基本狀態,它們是:初始態,執行態,等待狀態,就緒狀態,終止狀態。單機系統中進程通信有 4 種形式:主從式,會話式,消息或郵箱機制,共享存儲區方式,管道(共享大量內存中的數據)。

【線程】是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧,非共享),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源.

 

2.區別

1) 包含關係:一個程序至少有一個進程,一個進程至少有一個線程.

2) 內存共享:進程在執行過程中擁有獨立的內存單元(一個進程崩潰後,在保護模式下不會對其它進程產生影響);而多個線程共享進程提供的內存(擁有自己的私有棧空間只是作爲運行需要的極少內存),從而極大地提高了程序的運行效率,但一個線程死掉就等於整個進程死掉。所以多進程的程序要比多線程的程序健壯

3) 執行過程:進程獨立執行;線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。

4) 從邏輯角度來看,多線程的意義在於一個應用程序中,有多個執行部分可以同時執行。但操作系統並沒有將多個線程看做多個獨立的應用,來實現進程的調度和管理以及資源分配。這就是進程和線程的重要區別。

 

3.進程間通信

    進程的用戶空間是互相獨立的,一般而言是不能互相訪問的,唯一的例外是共享內存區。但是,系統空間卻是“公共場所”,所以內核顯然可以提供這樣的條件。除此以外,那就是雙方都可以訪問的外設了。在這個意義上,兩個進程當然也可以通過磁盤上的普通文件交換信息,或者通過“註冊表”或其它數據庫中的某些表項和記錄交換信息。廣義上這也是進程間通信的手段,但是一般都不把這算作“進程間通信”。因爲那些通信手段的效率太低了,而人們對進程間通信的要求是要有一定的實時性。 

  進程間通信主要包括管道, 系統IPC(包括消息隊列,信號量,共享存儲), SOCKET.
  管道包括三種:1)普通管道PIPE, 通常有種限制,一是半雙工,只能單向傳輸;二是只能在父子進程間使用. 2)流管道s_pipe: 去除了第一種限制,可以雙向傳輸. 3)命名管道:name_pipe, 去除了第二種限制,可以在許多並不相關的進程之間進行通訊.
  系統IPC的三種方式類同,都是使用了內核裏的標識符來識別. 
# 管道( pipe ):管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有親緣關係的進程間使用。進程的親緣關係通常是指父子進程關係。
# 有名管道 (named pipe) : 有名管道也是半雙工的通信方式,但是它允許無親緣關係進程間的通信。
# 信號量( semophore ) : 信號量是一個計數器,可以用來控制多個進程對共享資源的訪問。它常作爲一種鎖機制,防止某進程正在訪問共享資源時,其他進程也訪問該資源。因此,主要作爲進程間以及同一進程內不同線程之間的同步手段。
# 消息隊列( message queue ) : 消息隊列是由消息的鏈表,存放在內核中並由消息隊列標識符標識。消息隊列克服了信號傳遞信息少、管道只能承載無格式字節流以及緩衝區大小受限等缺點。
# 信號 ( sinal ) : 信號是一種比較複雜的通信方式,用於通知接收進程某個事件已經發生。
# 共享內存( shared memory ) :共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問。共享內存是最快的 IPC 方式,它是針對其他進程間通信方式運行效率低而專門設計的(共享大量內存中的數據)。它往往與其他通信機制,如信號兩,配合使用,來實現進程間的同步和通信。
# 套接字( socket ) : 套解口也是一種進程間通信機制,與其他通信機制不同的是,它可用於不同及其間的進程通信。

 

在知乎上看到一個網友對多線程的理解,覺得還挺好的。

 

作者:pansz
鏈接:https://www.zhihu.com/question/19901763/answer/13299543
來源:知乎
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
 

1。單進程單線程:一個人在一個桌子上吃菜。
2。單進程多線程:多個人在同一個桌子上一起吃菜。
3。多進程單線程:多個人每個人在自己的桌子上吃菜。

多線程的問題是多個人同時吃一道菜的時候容易發生爭搶,例如兩個人同時夾一個菜,一個人剛伸出筷子,結果伸到的時候已經被夾走菜了。。。此時就必須等一個人夾一口之後,在還給另外一個人夾菜,也就是說資源共享就會發生衝突爭搶。

 

1。對於 Windows 系統來說,【開桌子】的開銷很大,因此 Windows 鼓勵大家在一個桌子上吃菜。因此 Windows 多線程學習重點是要大量面對資源爭搶與同步方面的問題。

 

2。對於 Linux 系統來說,【開桌子】的開銷很小,因此 Linux 鼓勵大家儘量每個人都開自己的桌子吃菜。這帶來新的問題是:坐在兩張不同的桌子上,說話不方便。因此,Linux 下的學習重點大家要學習進程間通訊的方法。

--
補充:有人對這個開桌子的開銷很有興趣。我把這個問題推廣說開一下。

開桌子的意思是指創建進程。開銷這裏主要指的是時間開銷。
可以做個實驗:創建一個進程,在進程中往內存寫若干數據,然後讀出該數據,然後退出。此過程重複 1000 次,相當於創建/銷燬進程 1000 次。在我機器上的測試結果是: 
UbuntuLinux:耗時 0.8 秒 
Windows7:耗時 79.8 秒 
兩者開銷大約相差一百倍。

這意味着,在 Windows 中,進程創建的開銷不容忽視。換句話說就是,Windows 編程中不建議你創建進程,如果你的程序架構需要大量創建進程,那麼最好是切換到 Linux 系統。

大量創建進程的典型例子有兩個,一個是 gnu autotools 工具鏈,用於編譯很多開源代碼的,他們在 Windows 下編譯速度會很慢,因此軟件開發人員最好是避免使用 Windows。另一個是服務器,某些服務器框架依靠大量創建進程來幹活,甚至是對每個用戶請求就創建一個進程,這些服務器在 Windows 下運行的效率就會很差。這"可能"也是放眼全世界範圍,Linux 服務器遠遠多於 Windows 服務器的原因。

--
再次補充:如果你是寫服務器端應用的,其實在現在的網絡服務模型下,開桌子的開銷是可以忽略不計的,因爲現在一般流行的是按照 CPU 核心數量開進程或者線程,開完之後在數量上一直保持,進程與線程內部使用協程或者異步通信來處理多個併發連接,因而開進程與開線程的開銷可以忽略了。

另外一種新的開銷被提上日程:核心切換開銷。

現代的體系,一般 CPU 會有多個核心,而多個核心可以同時運行多個不同的線程或者進程。

當每個 CPU 核心運行一個進程的時候,由於每個進程的資源都獨立,所以 CPU 核心之間切換的時候無需考慮上下文。

當每個 CPU 核心運行一個線程的時候,由於每個線程需要共享資源,所以這些資源必須從 CPU 的一個核心被複制到另外一個核心,才能繼續運算,這佔用了額外的開銷。換句話說,在 CPU 爲多核的情況下,多線程在性能上不如多進程。

因而,當前面向多核的服務器端編程中,需要習慣多進程而非多線程。

一、進程間的通信方式

# 管道( pipe ):管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有親緣關係的進程間使用。進程的親緣關係通常是指父子進程關係。
# 有名管道 (namedpipe) : 有名管道也是半雙工的通信方式,但是它允許無親緣關係進程間的通信。
# 信號量(semophore ) : 信號量是一個計數器,可以用來控制多個進程對共享資源的訪問。它常作爲一種鎖機制,防止某進程正在訪問共享資源時,其他進程也訪問該資源。因此,主要作爲進程間以及同一進程內不同線程之間的同步手段。
# 消息隊列( messagequeue ) : 消息隊列是由消息的鏈表,存放在內核中並由消息隊列標識符標識。消息隊列克服了信號傳遞信息少、管道只能承載無格式字節流以及緩衝區大小受限等缺點。
# 信號 (sinal ) : 信號是一種比較複雜的通信方式,用於通知接收進程某個事件已經發生。
# 共享內存(shared memory ) :共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問。共享內存是最快的 IPC 方式,它是針對其他進程間通信方式運行效率低而專門設計的。它往往與其他通信機制,如信號兩,配合使用,來實現進程間的同步和通信。
# 套接字(socket ) : 套解口也是一種進程間通信機制,與其他通信機制不同的是,它可用於不同及其間的進程通信。

 

二、線程間的通信方式

 

# 鎖機制:包括互斥鎖、條件變量、讀寫鎖
   *互斥鎖提供了以排他方式防止數據結構被併發修改的方法。
   *讀寫鎖允許多個線程同時讀共享數據,而對寫操作是互斥的。
   *條件變量可以以原子的方式阻塞進程,直到某個特定條件爲真爲止。對條件的測試是在互斥鎖的保護下進行的。條件變量始終與互斥鎖一起使用。
# 信號量機制(Semaphore):包括無名線程信號量和命名線程信號量
# 信號機制(Signal):類似進程間的信號處理
    線程間的通信目的主要是用於線程同步,所以線程沒有像進程通信中的用於數據交換的通信機制。

 

線程之間同步方式有:臨界區、互斥區、事件、信號量。

發佈了48 篇原創文章 · 獲贊 31 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章