2010-03-20 95 views

回答

73

fork爲您提供了一個全新的進程,它是當前進程的副本,具有相同的代碼段。隨着內存映像更改(通常這是由於兩個進程的行爲不同),您會分離內存映像(寫入時複製),但可執行代碼保持不變。任務不會共享內存,除非他們使用一些原始的內存。

一個進程可以有多個線程,每個線程在進程的相同上下文中並行執行。內存和其他資源由線程共享,因此共享數據必須通過一些基本和同步對象(如mutexes,condition variablessemaphores)訪問,以避免數據損壞。

+3

您可能希望將「當前進程的副本」稱爲子進程。 – 2010-03-20 13:25:43

+1

然而,文本段通常是共享的(虛擬的),甚至數據段也可以是寫入時拷貝。 – Xailor 2012-02-29 19:27:04

+0

使用線程定義線程不是一個好主意... – nbro 2016-03-15 18:26:04

26

Dacav的答案非常好,我只想補充一點,並非所有線程模型都能爲您提供真正的多處理。

例如,Ruby的默認線程實現不使用真正的OS /內核線程。相反,它通過在單個內核線程/進程內的線程對象之間切換來模擬多線程。

這對於多處理器/多核系統非常重要,因爲這些輕量級線程類型只能在單個核心上運行 - 您不會因爲擁有多個線程而提高性能。

這有所作爲的另一個地方是當一個線程阻塞(等待I/O或調用驅動程序的IOCTL)時,所有線程都會阻塞。

現在這不是很常見 - 大多數線程實現使用不受這些問題影響的內核線程 - 但它的價值在於完整性。

相比之下,fork爲您提供了另一個可以在原始進程執行時同時在另一個物理CPU上運行的進程。有些人認爲IPC更適合他們的應用程序,其他人更喜歡線程。

祝你好運,玩得開心!多線程既具有挑戰性又有收穫。

+6

+1爲了一個神經:「不是所有的線程都能爲你提供真正的多處理「 – Dacav 2010-03-20 15:53:02

+0

ruby​​> = 2.0支持OS /內核線程。 – 2015-12-01 08:53:09

5

線程是並行運行的函數,fork是父進程繼承的新進程。 線程可以並行執行任務,而fork是獨立的進程,也可以同時運行。 線程具有競爭條件,並且在那裏控制信號量和鎖或互斥體,管道既可以在叉和線程中使用。

63

叉:

叉只不過是一個新的工藝,看起來酷似老或父進程,但仍然是一個不同的過程用不同的進程ID,並有它自己的內存。父進程爲子進程創建一個單獨的地址空間。父進程和子進程都擁有相同的代碼段,但彼此獨立執行。

分叉最簡單的例子是當你在shell/unix/linux上運行命令時。每次用戶發出命令時,shell都會分叉一個子進程並完成任務。

發出fork系統調用時,會創建與父進程相對應的所有頁面的副本,並由子進程的操作系統裝載到單獨的內存位置,但在某些情況下,這不是必需的。與'exec'系統調用一樣,不需要複製父進程頁面,因爲execv替代了父進程本身的地址空間。

幾件事情需要注意分叉是:將有它自己獨特的進程ID

  • 子進程。
  • 子進程應該有它自己的父文件描述符副本。
  • 父進程設置的文件鎖不應該被子進程繼承。
  • 在父進程中打開的任何信號量也應該在子進程中打開。
  • 子進程應該有父節點的消息隊列描述符的副本。
  • 孩子將擁有自己的地址空間和內存。

主題:

線程是重量輕進程(LWP)。傳統上,一個線程只是一個包含遺留信息(數據,堆棧,I/O,信號)的CPU(和其他一些最小狀態)狀態。由於系統不爲流程初始化新的系統虛擬內存空間和環境,線程所需的開銷比「分流」或產生新流程的開銷少。雖然在多處理器系統中可以安排流程可以安排在另一個處理器上運行,從而通過並行或分佈式處理獲得速度,但在單處理器系統上也可以獲得收益,這些系統利用I/O和其他系統功能中的延遲,這些系統功能可能會暫停處理執行。

線程在同一進程共享:

  • 過程的指令
  • 大多數數據
  • 打開的文件(描述符)
  • 信號和信號處理程序
  • 當前工作目錄
  • 用戶和組ID爲

更多細節見here

+0

一個進程可以有多個線程。如果進程中的某個線程調用fork,分叉進程是否有完全複製的內存,但只有調用線程在新進程中? – Michael 2017-06-16 15:50:08

+0

答案:是的 https://stackoverflow.com/questions/10080811/what-happens-to-other-threads-when-one-thread-forks – Michael 2017-06-16 15:57:36

4
  1. 線程共享創建它的進程的地址空間;進程有自己的地址 空間。
  2. 線程可以直接訪問其進程的數據段;進程擁有自己的副本 父進程的數據段。
  3. 線程可以直接與其進程的其他線程通信;進程必須使用進程間通信與兄弟進程進行通信。
  4. 線程幾乎沒有開銷;流程有相當大的開銷。
  5. 新線程很容易創建;新流程需要重複父流程。
  6. 線程可以對同一進程的線程進行相當程度的控制;進程只能對子進程進行 運動控制。
  7. 對主線程的更改(取消,優先級更改等)可能會影響進程的其他線程的行爲;對父進程的更改不會影響子進程