最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

什么是多進(jìn)程程序和多線程程序

2020-09-19 00:06 作者:奧大梨呀  | 我要投稿

????談這個問題首先需要知道什么是進(jìn)程,什么是線程。這個問題在筆者剛接觸操作系統(tǒng)時也是一頭霧水。這里先貼出兩者的概念,然后我們再細(xì)細(xì)道來。

進(jìn)程(Process):計算機(jī)中的程序關(guān)于某數(shù)據(jù)集合上的一次運行活動,是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位。

線程(thread):操作系統(tǒng)能夠進(jìn)行運算調(diào)度的最小單位。它被包含在進(jìn)程之中,是進(jìn)程中的實際運作單位。

????首先來談一談進(jìn)程。進(jìn)程一般被定義為正在運行的程序的實例,包括運行的代碼和運行代碼所需要的資源。通俗的說就是,我們在寫一個C語言程序(如:Hello World)后,編譯后生成的可執(zhí)行文件,這個文件就是一個程序,執(zhí)行這個程序之后,操作系統(tǒng)就會執(zhí)行文件中的代碼,運行的這組代碼和所需要的資源就稱為進(jìn)程。進(jìn)程是動態(tài)的,且進(jìn)程的地址空間都是獨立的,互不影響。一個進(jìn)程只能對應(yīng)一個程序,但是一個程序可以對應(yīng)多個進(jìn)程,這就是后面要說的多進(jìn)程程序。

????再來談一談線程,在早期的操作系統(tǒng)是沒有線程這個概念的,后來隨著計算機(jī)的發(fā)展,越來越復(fù)雜的程序出現(xiàn)了,由于進(jìn)程之間的切換開銷比較大,因此線程被發(fā)明了。線程是程序執(zhí)行的最小單位,一個進(jìn)程可以包含多個線程,所有線程之間除了一些運行必要的資源(如棧),其他資源均共享。線程必須依賴于進(jìn)程,線程無法獨立運行。

如果你還不能理解進(jìn)程和線程的話,通過下面這個故事或許就能明白了。

在一個遙遠(yuǎn)的地方,有家工廠,這家工廠中有很多工人在打工,那么這家工廠對應(yīng)的就是一個進(jìn)程,它包含有工廠運作的資源和流程(代碼)。而這些工人對應(yīng)的就是許多的線程,他們共享這個工廠的資源,但是每個人都有自己負(fù)責(zé)的一部分工作內(nèi)容。但每個人都無法單干,必須依賴于工廠。(未完待續(xù)....)

????如果你還不能理解進(jìn)程和線程的話,沒關(guān)系,繼續(xù)看下去吧,也許看完就能理解了。

????說完了進(jìn)程和線程,現(xiàn)在來說一下什么是多進(jìn)程程序。正常情況下,我們所編寫的程序一般都是對應(yīng)一個進(jìn)程。如果需要對應(yīng)多個進(jìn)程就必須在代碼中創(chuàng)建進(jìn)程,創(chuàng)建進(jìn)程的進(jìn)程稱為父進(jìn)程,而被創(chuàng)建的進(jìn)程稱為子進(jìn)程。在類UNIX系統(tǒng)中使用fork函數(shù)創(chuàng)建進(jìn)程。fork函數(shù)沒有參數(shù),返回值為進(jìn)程的id(pid),神奇的是fork函數(shù)會返回2次,在父進(jìn)程中返回子進(jìn)程的id(pid),而在被創(chuàng)建的子進(jìn)程中返回0(創(chuàng)建失敗則返回-1)。因此在多進(jìn)程程序中需要判斷fork函數(shù)的返回值,然后執(zhí)行父進(jìn)程和子進(jìn)程的代碼。為什么需要判斷fork的返回值呢,因為fork創(chuàng)建子進(jìn)程時,會將父進(jìn)程的資源和代碼cpoy一份,即副本,因此子進(jìn)程的資源和代碼都與父進(jìn)程當(dāng)前的狀態(tài)相同(如父進(jìn)程已打開的文件,子進(jìn)程也是已打開),則唯一可以判斷是哪個進(jìn)程的方法就是fork函數(shù)的返回值了。根據(jù)這個返回值可以讓兩個資源代碼都相同的進(jìn)程分別執(zhí)行不同的代碼。下面這個例子就是使用fork創(chuàng)建子進(jìn)程后,令父進(jìn)程每隔1S輸出一個字符串,子進(jìn)程每隔2S輸出一個字符串,最后父進(jìn)程等待子進(jìn)程的返回后才返回(否則就要被當(dāng)成“孤兒進(jìn)程”讓init進(jìn)程抱走了)。

多進(jìn)程程序示例

這個程序的運行結(jié)果是這樣的:


多進(jìn)程程序運行結(jié)果

????接下來我們繼續(xù)講那個故事。但這次我們講的是前傳,時間線在更早的時候。

????在那個遙遠(yuǎn)的地方,有一位商人在那里蓋了幾間一樣的工廠來制作某種產(chǎn)品,但因為當(dāng)時技術(shù)比較落后,一間工廠的供電只夠一臺設(shè)備運行,而一個完整的產(chǎn)品的制作需要三個材料,這三個材料分別來自于三臺不同的設(shè)備。而且工廠剛起步,只能靠商人自己。因此為了效率,他不得不在工廠之間來回奔波,這個工廠制作第一個材料,而另一個工廠制作第二個材料....盡管如此麻煩,但是如果有一家工廠因故斷電了,其他工廠還能繼續(xù)運作。

????故事的這個部分的意思是,在線程還沒被發(fā)明時(技術(shù)落后),為了高效運行一個完整的程序(制作一個完整的產(chǎn)品),需要采用多進(jìn)程程序(多家工廠),這些進(jìn)程的代碼資源都是一樣的且互相獨立(工廠之間相同但互相獨立運作),一個進(jìn)程崩了(一家工廠沒電了),其他進(jìn)程不會受到影響(其他工廠不受影響)。由此可見,多進(jìn)程程序比較健壯,一個進(jìn)程的崩潰不容易導(dǎo)致其他進(jìn)程的崩潰,但進(jìn)程切換的開銷比較大(工廠之間來回奔波)。

????說完了多進(jìn)程程序,那么接下來就是多線程程序。同多進(jìn)程一樣,一般情況下,程序都是單線程,即主線程。如果要使用多線程,就需要進(jìn)行創(chuàng)建。在類UNIX系統(tǒng)中使用pthread_create函數(shù)來創(chuàng)建線程。它的函數(shù)原型如下:

pthread_create函數(shù)原型

此函數(shù)會創(chuàng)建一個線程,第一個參數(shù)tidp是指向保存線程ID的地址;第二個參數(shù)attr是設(shè)置線程的屬性,無特殊要求時設(shè)為NULL即可;第三個參數(shù)start_rtn是指向線程的入口地址,也就是一個函數(shù)指針,線程函數(shù)的原型必須與這個函數(shù)指針相同;而第四個參數(shù)arg就是要傳入線程的參數(shù),對應(yīng)線程函數(shù)參數(shù)的void*。線程之間共享進(jìn)程的資源,每個線程本身僅持有一些棧等必要資源,因此線程之間并發(fā)執(zhí)行效率較高。下面這個例子就是使用pthread_creat創(chuàng)建了一個線程,此線程和主線程并發(fā)執(zhí)行打印字符串,最后主線程等待這個線程的返回后才返回。

多線程程序示例

這個程序的運行結(jié)果是這樣的:

多線程程序運行結(jié)果

????最后讓我們把那個故事敘述完整。這次的時間線接在上一次講故事之后。

????后來,技術(shù)發(fā)展起來了,于是商人為了再次提高效率,就把其他工廠都拆了,用來改造剩下的最后一間工廠,改造完后,這間工廠的電力終于可以支撐3臺設(shè)備同時運行了。于是商人就可以在一間工廠里,(并發(fā))操作3臺機(jī)器來制作產(chǎn)品了,盡管他不能同時操作3臺機(jī)器,但是在切換使用機(jī)器時不需要像以前那樣辛苦了(工廠之間來回跑)。但是,存在一個安全隱患,如果一臺機(jī)器因為故障導(dǎo)致短路,那么整個工廠都會停電(咱們假設(shè)它只有總電源短路保護(hù))。

????故事的這個部分的意思是,線程被發(fā)明之后(技術(shù)發(fā)展起來),一個程序可以作為一個進(jìn)程被分為多個線程并發(fā)執(zhí)行(只在一家工廠分時操作3臺機(jī)器),相比于分成多個進(jìn)程并發(fā)執(zhí)行效率會更高(3家工廠來回跑)。但是,一但有一個線程崩潰了,那么這個進(jìn)程也崩了(一臺機(jī)器故障,整個工廠停電)。

????不過看到這你可能還有一個疑問,那開頭說的工人呢,他們哪去了?這就涉及到SMP了,所謂SMP就是指多核處理器。這里說的商人一個人單干指的就是單核處理器,而多核處理器就相當(dāng)于多請了幾個工人,前面說工人就相當(dāng)于線程,但并不是絕對,只是這樣說便于理解罷了,其實也可能相當(dāng)于進(jìn)程。不過,這是后話了,這里就不再多提。

????最后總結(jié)一下多進(jìn)程程序和多線程程序的區(qū)別:

????1.多進(jìn)程程序因為各進(jìn)程地址空間相互獨立,因此資源容易管理和保護(hù),但切換開銷較大。而多線程程序因為共享進(jìn)程資源,容易發(fā)生資源的爭搶,不利于資源的管理和保護(hù),但切換開銷較小。

????2.多進(jìn)程程序中一個進(jìn)程的崩潰一般不會導(dǎo)致其他進(jìn)程崩潰。而多線程程序的一個線程崩潰必然導(dǎo)致整個程序?qū)?yīng)的進(jìn)程的崩潰。

????對于這一點,我們可以打開一個瀏覽器,然后再打開任務(wù)管理器,點開瀏覽器應(yīng)用,會顯示瀏覽器應(yīng)用下的所有進(jìn)程,然后我們結(jié)束一個進(jìn)程后,瀏覽器并不會崩潰,因為它是多進(jìn)程程序,但是一定會有某個插件提示崩潰了,因為我們將它所對應(yīng)的進(jìn)程kill了。

QQ瀏覽器的進(jìn)程列表

????3.當(dāng)需要并發(fā)執(zhí)行且需要共享一些數(shù)據(jù)時,只能使用多線程,而不能使用多進(jìn)程。比如允許多個線程往一個文件寫入數(shù)據(jù),但不允許多個進(jìn)程往一個文件寫入數(shù)據(jù)。

????以上是筆者個人拙見,而且筆者文筆不是很好,有些比喻可能不太恰的,如果您覺得有不當(dāng)之處還請批評指正。


什么是多進(jìn)程程序和多線程程序的評論 (共 條)

分享到微博請遵守國家法律
莆田市| 阳曲县| 册亨县| 阿鲁科尔沁旗| 阳春市| 英德市| 剑川县| 景洪市| 海门市| 城市| 桃园县| 凌海市| 措勤县| 岫岩| 民丰县| 获嘉县| 丽水市| 汝南县| 陇南市| 璧山县| 驻马店市| 内丘县| 贵州省| 辉县市| 阿尔山市| 武夷山市| 类乌齐县| 黄浦区| 平顶山市| 洱源县| 盖州市| 罗平县| 临邑县| 监利县| 方山县| 白河县| 三江| 漯河市| 绥宁县| 陈巴尔虎旗| 湄潭县|