0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

進(jìn)程和線程的區(qū)別

科技綠洲 ? 來源:Linux開發(fā)架構(gòu)之路 ? 作者:Linux開發(fā)架構(gòu)之路 ? 2023-11-11 16:46 ? 次閱讀

1.什么是進(jìn)程?為什么要有進(jìn)程?

進(jìn)程有一個(gè)相當(dāng)精簡的解釋:進(jìn)程是對(duì)操作系統(tǒng)上正在運(yùn)行程序的一個(gè)抽象。

這個(gè)概念確實(shí)挺抽象,仔細(xì)想想?yún)s也挺精準(zhǔn)。

我們平常使用計(jì)算機(jī),都會(huì)在同一時(shí)間做許多事,比如邊看電影,邊微信聊天,順便打開瀏覽器百度搜索一下,我們所做的這么多事情背后都是一個(gè)個(gè)正在運(yùn)行中的軟件程序;這些軟件想要運(yùn)行起來,首先在磁盤上需要有各自的程序代碼,然后將代碼加載到內(nèi)存中,CPU會(huì)去執(zhí)行這些代碼,運(yùn)行中會(huì)產(chǎn)生很多數(shù)據(jù)需要存放,也可能需要和網(wǎng)卡、顯卡、鍵盤等外部設(shè)備交互,這背后其實(shí)就涉及到程序?qū)τ?jì)算機(jī)資源的使用,存在這么多程序,我們當(dāng)然需要想辦法管理程序資源的使用。并且CPU如果只有一個(gè),那么還需要操作系統(tǒng)調(diào)度CPU分配給各個(gè)程序使用,讓用戶感覺這些程序在同時(shí)運(yùn)行,不影響用戶體驗(yàn)。

理所當(dāng)然,操作系統(tǒng)會(huì)把每個(gè)運(yùn)行中的程序封裝成獨(dú)立的實(shí)體,分配各自所需要的資源,再根據(jù)調(diào)度算法切換執(zhí)行。這個(gè)抽象程序?qū)嶓w就是進(jìn)程。

所以很多對(duì)進(jìn)程的官方解釋中都會(huì)提到:進(jìn)程是操作系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)基本單位。

2.什么是線程?為什么要有線程?

在早期的操作系統(tǒng)中并沒有線程的概念,進(jìn)程是擁有資源和獨(dú)立運(yùn)行的最小單位,也是程序執(zhí)行的最小單位。任務(wù)調(diào)度采用的是時(shí)間片輪轉(zhuǎn)的搶占式調(diào)度方式,而進(jìn)程是任務(wù)調(diào)度的最小單位,每個(gè)進(jìn)程有各自獨(dú)立的內(nèi)存空間,使得各個(gè)進(jìn)程之間內(nèi)存地址相互隔離。

后來,隨著計(jì)算機(jī)行業(yè)的發(fā)展,程序的功能設(shè)計(jì)越來越復(fù)雜,我們的應(yīng)用中同時(shí)發(fā)生著多種活動(dòng),其中某些活動(dòng)隨著時(shí)間的推移會(huì)被阻塞,比如網(wǎng)絡(luò)請(qǐng)求、讀寫文件(也就是IO操作),我們自然而然地想著能不能把這些應(yīng)用程序分解成更細(xì)粒度、能 準(zhǔn)并行運(yùn)行 多個(gè)順序執(zhí)行實(shí)體,并且這些細(xì)粒度的執(zhí)行實(shí)體可以共享進(jìn)程的地址空間,也就是可以共享程序代碼、數(shù)據(jù)、內(nèi)存空間等,這樣程序設(shè)計(jì)模型會(huì)變得更加簡單。

其實(shí)很多計(jì)算機(jī)世界里的技術(shù)演變,都是模擬現(xiàn)實(shí)世界。比如我們把一個(gè)進(jìn)程當(dāng)成一個(gè)項(xiàng)目,當(dāng)項(xiàng)目任務(wù)變得復(fù)雜時(shí),自然想著能不能將項(xiàng)目按照業(yè)務(wù)、產(chǎn)品、工作方向等分成一個(gè)個(gè)任務(wù)模塊,分派給不同人員各自并行完成,再按照某種方式組織起各自的任務(wù)成果,最終完成項(xiàng)目。

需要多線程還有一個(gè)重要的理由就是:每個(gè)進(jìn)程都有獨(dú)立的代碼和數(shù)據(jù)空間(程序上下文),程序之間的切換會(huì)有較大的開銷;線程可以看做輕量級(jí)的進(jìn)程,同一類線程共享代碼和數(shù)據(jù)空間,每個(gè)線程都有自己獨(dú)立的運(yùn)行棧和程序計(jì)數(shù)器,線程之間切換的開銷小。所以線程的創(chuàng)建、銷毀、調(diào)度性能遠(yuǎn)遠(yuǎn)優(yōu)于進(jìn)程。

在引入多線程模型后,進(jìn)程和線程在程序執(zhí)行過程中的分工就相當(dāng)明確了,進(jìn)程負(fù)責(zé)分配和管理系統(tǒng)資源,線程負(fù)責(zé)CPU調(diào)度運(yùn)算,也是CPU切換時(shí)間片的最小單位。對(duì)于任何一個(gè)進(jìn)程來講,即便我們沒有主動(dòng)去創(chuàng)建線程,進(jìn)程也是默認(rèn)有一個(gè)主線程的。

3.它們在Linux內(nèi)核中實(shí)現(xiàn)方式有何不同?

在Linux 里面,無論是進(jìn)程,還是線程,到了內(nèi)核里面,我們統(tǒng)一都叫任務(wù)(Task),由一個(gè)統(tǒng)一的結(jié)構(gòu) task_struct 進(jìn)行管理,這個(gè)task_struct 數(shù)據(jù)結(jié)構(gòu)非常復(fù)雜,囊括了進(jìn)程管理生命周期中的各種信息。

圖片

在Linux操作系統(tǒng)內(nèi)核初始化時(shí)會(huì)創(chuàng)建第一個(gè)進(jìn)程,即0號(hào)創(chuàng)始進(jìn)程。隨后會(huì)初始化1號(hào)進(jìn)程(用戶進(jìn)程祖宗:/usr/lib/systemd/systemd),2號(hào)進(jìn)程(內(nèi)核進(jìn)程祖宗:[kthreadd]),其后所有的進(jìn)程線程都是在他們的基礎(chǔ)上fork出來的。

圖片

圖片

我們一般都是通過fork系統(tǒng)調(diào)用來創(chuàng)建新的進(jìn)程,fork 系統(tǒng)調(diào)用包含兩個(gè)重要的事件,一個(gè)是將 task_struct 結(jié)構(gòu)復(fù)制一份并且初始化,另一個(gè)是試圖喚醒新創(chuàng)建的子進(jìn)程。

我們說無論是進(jìn)程還是線程,在內(nèi)核里面都是task,管起來不是都一樣嗎?到底如何區(qū)分呢?其實(shí),線程不是一個(gè)完全由內(nèi)核實(shí)現(xiàn)的機(jī)制,它是由內(nèi)核態(tài)和用戶態(tài)合作完成的。

創(chuàng)建進(jìn)程的話,調(diào)用的系統(tǒng)調(diào)用是 fork,會(huì)將五大結(jié)構(gòu) files_struct、fs_struct、sighand_struct、signal_struct、mm_struct 都復(fù)制一遍,從此父進(jìn)程和子進(jìn)程各用各的數(shù)據(jù)結(jié)構(gòu)。而創(chuàng)建線程的話,調(diào)用的是系統(tǒng)調(diào)用 clone,五大結(jié)構(gòu)僅僅是引用計(jì)數(shù)加一,也即線程共享進(jìn)程的數(shù)據(jù)結(jié)構(gòu)。

4.所以它們到底有哪些區(qū)別?

功能:進(jìn)程是操作系統(tǒng)資源分配的基本單位,而線程是任務(wù)調(diào)度和執(zhí)行的基本單位

開銷:每個(gè)進(jìn)程都有獨(dú)立的內(nèi)存空間,存放代碼和數(shù)據(jù)段等,程序之間的切換會(huì)有較大的開銷;線程可以看做輕量級(jí)的進(jìn)程,共享內(nèi)存空間,每個(gè)線程都有自己獨(dú)立的運(yùn)行棧和程序計(jì)數(shù)器,線程之間切換的開銷小。

運(yùn)行環(huán)境:在操作系統(tǒng)中能同時(shí)運(yùn)行多個(gè)進(jìn)程;而在同一個(gè)進(jìn)程(程序)中有多個(gè)線程同時(shí)執(zhí)行(通過CPU調(diào)度,在每個(gè)時(shí)間片中只有一個(gè)線程執(zhí)行)

創(chuàng)建過程:在創(chuàng)建新進(jìn)程的時(shí)候,會(huì)將父進(jìn)程的所有五大數(shù)據(jù)結(jié)構(gòu)復(fù)制新的,形成自己新的內(nèi)存空間數(shù)據(jù),而在創(chuàng)建新線程的時(shí)候,則是引用進(jìn)程的五大數(shù)據(jù)結(jié)構(gòu)數(shù)據(jù),但是線程會(huì)有自己的私有數(shù)據(jù)、??臻g。

進(jìn)程和線程其實(shí)在cpu看來都是task_struct結(jié)構(gòu)的一個(gè)封裝,執(zhí)行不同task即可,而且在cpu看來就是在執(zhí)行這些task時(shí)候遵循對(duì)應(yīng)的調(diào)度策略以及上下文資源切換定義,包括寄存器地址切換,內(nèi)核棧切換。所以對(duì)于cpu而言,進(jìn)程和線程是沒有區(qū)別的。

附:我們通常所說的上下文切換具體指什么?

操作系統(tǒng)抽象出一個(gè)進(jìn)程的概念,讓應(yīng)用程序?qū)P挠趯?shí)現(xiàn)自己的業(yè)務(wù)邏輯既可,對(duì)應(yīng)用程序屏蔽了CPU調(diào)度、內(nèi)存管理等硬件細(xì)節(jié),而且在有限的CPU上可以“同時(shí)”進(jìn)行許多個(gè)任務(wù)。但是它為用戶帶來方便的同時(shí),也引入了一些額外的開銷。

在操作系統(tǒng)中,由于CPU的時(shí)間片調(diào)度策略,從一個(gè)進(jìn)程切換到另一個(gè)進(jìn)程需要保存當(dāng)前進(jìn)程的狀態(tài)并恢復(fù)另一個(gè)進(jìn)程的狀態(tài):當(dāng)前運(yùn)行任務(wù)轉(zhuǎn)為就緒(或者掛起、刪除)狀態(tài),另一個(gè)被選定的就緒任務(wù)成為當(dāng)前任務(wù)。上下文切換包括保存當(dāng)前任務(wù)的運(yùn)行環(huán)境,恢復(fù)將要運(yùn)行任務(wù)的運(yùn)行環(huán)境。

在上下文切換過程中,CPU會(huì)停止處理當(dāng)前運(yùn)行的程序,并保存當(dāng)前程序運(yùn)行的具體位置以便之后繼續(xù)運(yùn)行。從這個(gè)角度來看,上下文切換有點(diǎn)像我們同時(shí)閱讀幾本書,在來回切換書本的同時(shí)我們需要記住每本書當(dāng)前讀到的頁碼。

在三種情況下可能會(huì)發(fā)生上下文切換:中斷處理,多任務(wù)處理,內(nèi)核/用戶態(tài)切換。

在中斷處理中,其他程序”打斷”了當(dāng)前正在運(yùn)行的程序。當(dāng)CPU接收到中斷請(qǐng)求時(shí),會(huì)在正在運(yùn)行的程序和發(fā)起中斷請(qǐng)求的程序之間進(jìn)行一次上下文切換。

在多任務(wù)處理中,CPU會(huì)在不同程序之間來回切換,每個(gè)程序都有相應(yīng)的處理時(shí)間片,CPU在兩個(gè)時(shí)間片的間隔中進(jìn)行上下文切換。

在Linux中進(jìn)行內(nèi)核/用戶態(tài)切換也會(huì)進(jìn)行上下文切換,進(jìn)行系統(tǒng)調(diào)用時(shí),CPU寄存器里原來用戶態(tài)的指令位置需要先保存起來。接著,為了執(zhí)行內(nèi)核態(tài)代碼,CPU寄存器需要更新為內(nèi)核態(tài)指令的新位置。最后才是跳轉(zhuǎn)到內(nèi)核態(tài)運(yùn)行內(nèi)核任務(wù)。而系統(tǒng)調(diào)用結(jié)束后,CPU寄存器需要恢復(fù)原來保存的用戶態(tài),然后再切換到用戶空間,繼續(xù)運(yùn)行進(jìn)程,所以一次系統(tǒng)調(diào)用的過程,其實(shí)是發(fā)生了兩次CPU上下文切換。

CPU上下文切換,是保證Linux系統(tǒng)正常工作的核心功能之一,一般情況下不需要我們特別關(guān)注。

但過多的上下文切換,會(huì)把CPU時(shí)間消耗在寄存器、內(nèi)核棧以及虛擬內(nèi)存等數(shù)據(jù)的保存和恢復(fù)上,從而縮短進(jìn)程真正運(yùn)行的時(shí)間,導(dǎo)致系統(tǒng)的整體性能大幅下降。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • cpu
    cpu
    +關(guān)注

    關(guān)注

    68

    文章

    10889

    瀏覽量

    212373
  • 操作系統(tǒng)
    +關(guān)注

    關(guān)注

    37

    文章

    6859

    瀏覽量

    123498
  • 線程
    +關(guān)注

    關(guān)注

    0

    文章

    505

    瀏覽量

    19715
  • 進(jìn)程
    +關(guān)注

    關(guān)注

    0

    文章

    203

    瀏覽量

    13969
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    進(jìn)程線程的概念及其區(qū)別

    今天浩道跟大家分享一篇關(guān)于進(jìn)程線程之間關(guān)聯(lián)的硬核干貨,看看大神如何通過通俗易懂的圖文,讓大家更加深刻理解進(jìn)程線程區(qū)別!
    的頭像 發(fā)表于 11-21 10:50 ?938次閱讀
    <b class='flag-5'>進(jìn)程</b>和<b class='flag-5'>線程</b>的概念及其<b class='flag-5'>區(qū)別</b>

    #硬聲創(chuàng)作季 程序員知識(shí):【進(jìn)程管理】進(jìn)程線程區(qū)別

    計(jì)算機(jī)原理cpu/soc
    Mr_haohao
    發(fā)布于 :2022年09月16日 19:19:55

    Java語言核心基礎(chǔ)語法325-進(jìn)程線程區(qū)別

    JAVA
    電子學(xué)習(xí)
    發(fā)布于 :2023年01月16日 16:00:48

    進(jìn)程線程區(qū)別

    線程是指進(jìn)程內(nèi)的一個(gè)執(zhí)行單元,也是進(jìn)程內(nèi)的可調(diào)度實(shí)體.與進(jìn)程區(qū)別:(1)地址空間:進(jìn)程內(nèi)的一個(gè)
    發(fā)表于 12-12 09:28

    進(jìn)程線程區(qū)別

    `1、進(jìn)程線程區(qū)別和聯(lián)系進(jìn)程(process)和線程(thread)是操作系統(tǒng)的基本概念,但是它們比較抽象,不容易掌握。計(jì)算機(jī)的核心是C
    發(fā)表于 11-30 14:06

    進(jìn)程線程區(qū)別和聯(lián)系介紹

    發(fā)生了變化:它只是資源分配的單位,而不再是調(diào)度運(yùn)行的單位 。在微內(nèi)核系統(tǒng)中,真正調(diào)度運(yùn)行的基本單位是線程。因此,實(shí)現(xiàn)并發(fā)功能的單位是線程線程概念   線程
    發(fā)表于 07-04 00:18

    Linux進(jìn)程線程區(qū)別是什么?

    Linux進(jìn)程線程區(qū)別是什么為什么要使用線程?線程操作的函數(shù)
    發(fā)表于 03-11 06:13

    進(jìn)程線程區(qū)別在哪?

    1、進(jìn)程線程區(qū)別:1. 線程是程序執(zhí)行的最小單位,而進(jìn)程是操作系統(tǒng)分配資源的最小單位;2. 一個(gè)進(jìn)程
    發(fā)表于 07-07 06:53

    進(jìn)程線程區(qū)別是什么

    有了提前批的失敗經(jīng)驗(yàn),接下來不斷的總結(jié)鞏固和修正錯(cuò)誤,這次發(fā)揮要比上次要好很多。一面(電話面)自我介紹進(jìn)程線程區(qū)別線程同步和通信鎖機(jī)制以及死鎖條件和預(yù)防TCP/IP協(xié)議的一些基礎(chǔ)知識(shí)C++的構(gòu)造
    發(fā)表于 12-23 07:28

    進(jìn)程線程區(qū)別和聯(lián)系

    進(jìn)程(process)和線程(thread)是操作系統(tǒng)的基本概念,但是它們比較抽象,不容易掌握。 最近,我讀到一篇材料,發(fā)現(xiàn)有一個(gè)很好的類比,可以把它們解釋地清晰易懂。 1、計(jì)算機(jī)的核心是 CPU
    的頭像 發(fā)表于 12-05 18:22 ?1062次閱讀

    進(jìn)程切換與線程切換有啥區(qū)別

    注意這個(gè)題目問的是進(jìn)程**切換**與線程**切換**的區(qū)別,不是進(jìn)程線程區(qū)別。當(dāng)然這里的**
    的頭像 發(fā)表于 02-24 14:16 ?598次閱讀

    進(jìn)程線程區(qū)別

    每個(gè)進(jìn)程都有獨(dú)立的代碼和數(shù)據(jù)空間(程序上下文),程序之間的切換會(huì)有較大的開銷;線程可以看做輕量級(jí)的進(jìn)程,同一類線程共享代碼和數(shù)據(jù)空間,每個(gè)線程
    的頭像 發(fā)表于 05-09 11:06 ?6050次閱讀
    <b class='flag-5'>進(jìn)程</b>和<b class='flag-5'>線程</b>的<b class='flag-5'>區(qū)別</b>

    程序中進(jìn)程線程區(qū)別

    什么是進(jìn)程 1、進(jìn)程線程區(qū)別 進(jìn)程是指正在運(yùn)行的程序,它擁有獨(dú)立的內(nèi)存空間和系統(tǒng)資源,不同進(jìn)程
    的頭像 發(fā)表于 06-22 11:39 ?692次閱讀
    程序中<b class='flag-5'>進(jìn)程</b>和<b class='flag-5'>線程</b>的<b class='flag-5'>區(qū)別</b>

    進(jìn)程線程區(qū)別以及優(yōu)缺點(diǎn)

    進(jìn)程線程 1、什么是進(jìn)程、線程,有什么區(qū)別? 進(jìn)程是資源(CPU、內(nèi)存等)分配的基本單位,
    的頭像 發(fā)表于 07-21 11:02 ?1413次閱讀

    嵌入式進(jìn)程線程區(qū)別

    需要進(jìn)行大量計(jì)算的優(yōu)先使用線程 所謂大量計(jì)算,當(dāng)然就是要耗費(fèi)很多CPU,切換頻繁了,這種情況下線程是最合適的。這種原則最常見的是圖像處理、算法處理。
    發(fā)表于 09-04 10:05 ?510次閱讀
    嵌入式<b class='flag-5'>進(jìn)程</b>和<b class='flag-5'>線程</b>的<b class='flag-5'>區(qū)別</b>