進程和線程的區別

       進程是線程的容器,有獨立的地址空間,可以有多個線程,不直接執行代碼。線程在進程中,沒有獨立的地址空間,共享全局和堆,有獨自的棧區。

進程間切換要切換地址空間,開銷大,而線程開銷小。(本質區別在於是否存在獨立的地址空間)

總的來說就是:進程有獨立的地址空間,線程沒有單獨的地址空間(同一進程內的線程共享進程的地址空間)。(下面的內容摘自Linux下的多線程編程)

使用多線程的理由之一是和進程相比,它是一種非常"節儉"的多任務操作方式。我們知道,在Linux系統下,啓動一個新的進程必須分配給它獨立的地址空間,建立衆多的數據表來維護它的代碼段、堆棧段和數據段,這是一種"昂貴"的多任務工作方式。而運行於一個進程中的多個線程,它們彼此之間使用相同的地址空間,共享大部分數據,啓動一個線程所花費的空間遠遠小於啓動一個進程所花費的空間,而且,線程間彼此切換所需的時間也遠遠小於進程間切換所需要的時間。據統計,總的說來,一個進程的開銷大約是一個線程開銷的30倍左右,當然,在具體的系統上,這個數據可能會有較大的區別。

使用多線程的理由之二是線程間方便的通信機制。對不同進程來說,它們具有獨立的數據空間,要進行數據的傳遞只能通過通信的方式進行,這種方式不僅費時,而且很不方便。線程則不然,由於同一進程下的線程之間共享數據空間,所以一個線程的數據可以直接爲其它線程所用,這不僅快捷,而且方便。當然,數據的共享也帶來其他一些問題,有的變量不能同時被兩個線程所修改,有的子程序中聲明爲static的數據更有可能給多線程程序帶來災難性的打擊,這些正是編寫多線程程序時最需要注意的地方。

線程同步:互斥,關鍵代碼,消息隊列,文件鎖

進程通信:管道,消息隊列 socket



特定操作系統的進程和線程操作系統

進程和線程是依賴於特定的操作系統的, 譬如Windows和Linux在實現進程和線程就有很大的差異, 這一部分主要說明 Windows和Linux下進程和線程的一些特定的特徵.

Windows

通常做過Windows多任務系統開發的程序員肯定會知道, Windows中的進程比線程有很大的開銷, 要一定堅持使用線程


Linux

那麼, 在Linux下 進程和線程真的沒有本質區別嗎?


首先大家可以參考這個帖子, Threads vs Processes in Linux.


下面內容摘自 Threads vs Processes in Linux.


Linux uses a 1-1 threading model, with (to the kernel) no distinction between processes and threads-- everything is simply a runnable task. *

On Linux, the system call clone clones a task, with a configurable level of sharing, among which are:

CLONE_FILES: share the same file descriptor table (instead of creating a copy)

CLONE_PARENT: don't set up a parent-child relationship between the new task and the old

(otherwise, child's getppid() = parent's getpid())

CLONE_VM: share the same memory space (instead of creating a COW copy)

fork() calls clone(least sharing) and pthread_create() calls clone(most sharing). **

forking costs a tiny bit more than pthread_createing because of copying tables and creating COW mappings for memory,

but the Linux kernel developers have tried (and succeeded) at minimizing those costs.

Switching between tasks, if they share the same memory space and various tables, will be a tiny bit cheaper

than if they aren't shared, because the data may already be loaded in cache. However,

switching tasks is still very fast even if nothing is shared -- this is something else that Linux kernel developers

try to ensure (and succeed at ensuring).

In fact, if you are on a multi-processor system, not sharing may actually be a performance boon:

if each task is running on a different processor, synchronizing shared memory is expensive.

上面其實已經講得很清楚了,


對於內核而言, 進程和線程是 沒有區別的

在用戶的角度而言,區別在於如何創建(clone), 如果使用是 least shared ,那麼就類似於進程的創建(最少共享)

如果使用的是 most sharing 那麼就類似於線程的創建(最多共享)

由於Linux內核開發人員的努力和優化, 創建, 切換, 關閉 進程和線程之前的開銷差異已經十分的小了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章