學(xué)習(xí)啦 > 學(xué)習(xí)電腦 > 操作系統(tǒng) > 操作系統(tǒng)基礎(chǔ)知識(shí) > Linux操作系統(tǒng)的進(jìn)程和線程的詳解

Linux操作系統(tǒng)的進(jìn)程和線程的詳解

時(shí)間: 佳洲1085 分享

Linux操作系統(tǒng)的進(jìn)程和線程的詳解

  Linux操作系統(tǒng)中進(jìn)程和線程是一對(duì)經(jīng)常搞混概念的名詞術(shù)語(yǔ),下面由學(xué)習(xí)啦小編為大家整理了Linux操作系統(tǒng)的進(jìn)程和線程詳解的相關(guān)知識(shí),希望對(duì)大家有幫助!

  Linux操作系統(tǒng)的進(jìn)程和線程的詳解一、進(jìn)程和線程的定義

  首先我們先要弄清楚二者的定義, 究竟什么是進(jìn)程, 什么又是線程?

  根據(jù) wikipedia process 中的定義, 進(jìn)程是一個(gè)計(jì)算機(jī)程序的實(shí)例,由一個(gè)或者多個(gè)線程組成.

  同樣在 wikipedia thread 中對(duì)線程的定義是: 線程的執(zhí)行是由計(jì)算機(jī)的fork操作來(lái)將一個(gè)程序生成一個(gè)或者多個(gè)并發(fā)的運(yùn)行任務(wù).

  在單核的計(jì)算機(jī)中, 線程并非 真正并行 的, 而是 分時(shí)的并發(fā)。

  也就是說(shuō)多個(gè)線程無(wú)需等待另一個(gè)線程的完成,而只需要等待CPU的時(shí)間片.

  在多核的計(jì)算機(jī)中,多個(gè)線程可以真正的并行,也就是同時(shí)執(zhí)行,同時(shí)獲得CPU時(shí)間片.

  同樣, 在現(xiàn)代計(jì)算機(jī)中, 通常都是 分時(shí)操作系統(tǒng) (time sharing), 也就是不同的進(jìn)程通過(guò)時(shí)間片來(lái)獲得CPU的控制權(quán), 來(lái)執(zhí)行自己的代碼. 同樣,單核的系統(tǒng)進(jìn)程也只能是并發(fā)的, 而多核的系統(tǒng)可以達(dá)到并行.

  Linux操作系統(tǒng)的進(jìn)程和線程的詳解二、進(jìn)程和線程的聯(lián)系

  二者的關(guān)系可以簡(jiǎn)單的一句話概括為, 通常, 一個(gè)進(jìn)程可以包括多個(gè)線程, 一個(gè)線程只能屬于一個(gè)進(jìn)程.

  一個(gè)進(jìn)程可以生成多個(gè)線程,而這些線程之前共享地址空間和相應(yīng)的資源, 在線程切換時(shí), 并沒(méi)有太多的開銷.

  進(jìn)程和線程在共享地址空間和資源的區(qū)別.

  那么, 對(duì)于同樣一個(gè)應(yīng)用,我們可以選擇 進(jìn)程 來(lái)實(shí)現(xiàn), 也可以選擇 線程 來(lái)實(shí)現(xiàn), 那么二者有什么區(qū)別呢? 我們應(yīng)該如何選擇呢?

  Linux操作系統(tǒng)的進(jìn)程和線程的詳解三、進(jìn)程和線程的區(qū)別

  從本質(zhì)上說(shuō),二者只是在 是否共享地址空間,及共享多少地址空間 上是有差別的,而至于其它的區(qū)別也都是 因?yàn)檫@個(gè)本質(zhì)區(qū)別來(lái)引起的. 下面逐一地進(jìn)行簡(jiǎn)單的說(shuō)明.

  關(guān)于共享地址空間

  傳統(tǒng)意義上, 進(jìn)程之間是不共享地址空間的, 而線程是共享著進(jìn)程的地址空間.

  但是在Linux中, 會(huì)有不同, 請(qǐng)參考下面 特定操作系統(tǒng)的進(jìn)程和線程 部分的詳細(xì)說(shuō)明.

  安全性

  因?yàn)檫M(jìn)程之前是不共享資源和地址空間的,所以不會(huì)存在太多的安全問(wèn)題(相比于線程).

  而由于多個(gè)線程共享著相同的地址空間和資源,所以會(huì)存在線程之間有可能會(huì)惡意修改或者獲取非授權(quán)數(shù)據(jù)的可能.

  這也就是為什么近期, chrome和IE8相繼開始使用多進(jìn)程來(lái)替代之前的多線程(不同的tab之間).

  健壯性

  由于多個(gè)線程共享同一個(gè)進(jìn)程的地址空間和相關(guān)的資源, 所以當(dāng)一個(gè)線程出現(xiàn)crash,那么可能會(huì)導(dǎo)致相應(yīng)的地址空間和資源 會(huì)出現(xiàn)問(wèn)題,從而導(dǎo)致其它的線程也crash. 這個(gè)也很好理解,一個(gè)簡(jiǎn)單的大家可能都經(jīng)歷過(guò)的就是IE7吧, 當(dāng)一個(gè)tab突然崩潰時(shí),所有的tab都會(huì)崩潰,這時(shí)通常IE要重啟(重啟進(jìn)程,重新生成線程).

  而多進(jìn)程則不存在這個(gè)問(wèn)題, 因?yàn)椴煌牡刂房臻g和資源, 當(dāng)一個(gè)進(jìn)程崩潰時(shí), 并不會(huì)影響到其它進(jìn)程. 同樣,如果你用過(guò)chrome,如果一個(gè)tab崩潰了(chrome那搞笑的提示信息), 我們只需要關(guān)掉這個(gè)tab即可,并 不會(huì)影響到其它的tab.

  性能

  進(jìn)程的安全性,健壯性是建立在獨(dú)立的地址空間和獨(dú)立的資源的條件下的, 所以進(jìn)程的 啟動(dòng), 關(guān)閉, 切換 相比于線程會(huì)有更多的開銷. 而這種開銷的差別在Windows下更加顯著, 請(qǐng)參考下面 特定操作系統(tǒng)的進(jìn)程和線程部分的詳細(xì)說(shuō)明.

  Linux操作系統(tǒng)的進(jìn)程和線程的詳解四、特定操作系統(tǒng)的進(jìn)程和線程

  進(jìn)程和線程是依賴于特定的操作系統(tǒng)的, 譬如Windows和Linux在實(shí)現(xiàn)進(jìn)程和線程就有很大的差異, 這一部分主要說(shuō)明 Windows和Linux下進(jìn)程和線程的一些特定的特征.

  Windows

  通常做過(guò)Windows多任務(wù)系統(tǒng)開發(fā)的程序員肯定會(huì)知道, Windows中的進(jìn)程比線程有很大的開銷, 要一定堅(jiān)持使用線程, 那么為什么呢?

  這里有個(gè)討論可供參考: Why is creating a new process more expensive on Windows than Linux?

  簡(jiǎn)單總結(jié)下, 原因:

  這是Windows的設(shè)計(jì)的理念所致(多用戶和并行的要求不高的特性)

  在創(chuàng)建進(jìn)程時(shí),會(huì)有相當(dāng)?shù)南到y(tǒng)調(diào)用

  Linux

  讓我們回到本文的摘要部分的引入, 我的室友提出的對(duì)于我而言 聞所未聞 的新觀點(diǎn).

  那么, 在Linux下 進(jìn)程和線程真的沒(méi)有本質(zhì)區(qū)別嗎?

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

  下面內(nèi)容摘自 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.

  上面其實(shí)已經(jīng)講得很清楚了,

  對(duì)于內(nèi)核而言, 進(jìn)程和線程是 沒(méi)有區(qū)別的

  在用戶的角度而言,區(qū)別在于如何創(chuàng)建(clone), 如果使用是 least shared ,那么就類似于進(jìn)程的創(chuàng)建(最少共享)

  如果使用的是 most sharing 那么就類似于線程的創(chuàng)建(最多共享)

  由于Linux內(nèi)核開發(fā)人員的努力和優(yōu)化, 創(chuàng)建, 切換, 關(guān)閉 進(jìn)程和線程之前的開銷差異已經(jīng)十分的小了

3637770