進(jìn)程和線程的基本概念
進(jìn)程(Process)就是一個(gè)應(yīng)用程序在處理機(jī)上的一次執(zhí)行過程,它是一個(gè)動(dòng)態(tài)的概念,而線程(thread)是進(jìn)程中的一部分,進(jìn)程中包含了多個(gè)線程在運(yùn)行。對(duì)于移動(dòng)端來說,你可以把不同的手機(jī)應(yīng)用當(dāng)成多個(gè)進(jìn)程,而把每個(gè)應(yīng)用這一進(jìn)程中執(zhí)行的網(wǎng)絡(luò)請(qǐng)求/圖片加載等操作當(dāng)作多個(gè)線程來看待。
- 進(jìn)程是具有一定獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合上的一次運(yùn)行活動(dòng),是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位。
- 線程是進(jìn)程的一個(gè)實(shí)體, 是CPU調(diào)度和分派的基本單位,它是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位.線程自己基本上不擁有系統(tǒng)資源,只擁有一點(diǎn)在運(yùn)行中必不可少的資源(如程序計(jì)數(shù)器,一組寄存器和棧),但是它可與同屬一個(gè)進(jìn)程的其他的線程共享進(jìn)程所擁有的全部資源(如虛擬地址空間、文件描述符等)。
- 一個(gè)線程可以創(chuàng)建和撤銷另一個(gè)線程,同一個(gè)進(jìn)程中的多個(gè)線程之間可以并發(fā)執(zhí)行。
進(jìn)程和線程的主要差別在于它們是不同的操作系統(tǒng)資源管理方式。進(jìn)程有獨(dú)立的地址空間,一個(gè)進(jìn)程崩潰后,在保護(hù)模式下不會(huì)對(duì)其它進(jìn)程產(chǎn)生影響,而線程只是一個(gè)進(jìn)程中的不同執(zhí)行路徑。線程有自己的堆棧和局部變量,但線程之間沒有單獨(dú)的地址空間,一個(gè)線程死掉就等于整個(gè)進(jìn)程死掉,所以多進(jìn)程的程序要比多線程的程序 健壯,但在進(jìn)程切換時(shí),耗費(fèi)資源較大,效率要差一些。但對(duì)于一些要求同時(shí)進(jìn)行并且又要共享某些變量的并發(fā)操作,只能用線程,不能用進(jìn)程。
多線程編程
我們都知道在代碼運(yùn)行過程中,最終會(huì)變?yōu)闄C(jī)器可理解的二進(jìn)制代碼,但是一個(gè)cpu一次只能執(zhí)行一個(gè)命令,就如下圖所示:

但是對(duì)于多處理器和多核計(jì)算機(jī)來說,利用多線程的程序?qū)⒁粋€(gè)進(jìn)程分解為若干個(gè)線程,可以在某個(gè)線程和其他線程之間反復(fù)多次的進(jìn)行上下文切換,從而實(shí)現(xiàn)切換執(zhí)行cpu命令列,因此看上去就好像1個(gè)cpu能夠并發(fā)執(zhí)行多個(gè)線程一樣。而對(duì)于真正具有多個(gè)cpu的機(jī)器來說,多個(gè)cpu可以在同時(shí)執(zhí)行命令,是在真正意義上提供了多個(gè)cpu以并發(fā)執(zhí)行多個(gè)線程任務(wù)的功能,有效地利用了多處理器的特性,從而就能提高整個(gè)進(jìn)程的執(zhí)行速度。而這種做法也就是我們常說的多線程編程。
但是實(shí)際上,在多線程編程中容易發(fā)生各種問題。比如多個(gè)線程更新相同的資源會(huì)導(dǎo)致數(shù)據(jù)不一致(數(shù)據(jù)競(jìng)爭(zhēng))/停止等待事件的線程會(huì)導(dǎo)致多個(gè)線程相互循環(huán)等待(死鎖)/使用過多線程會(huì)造成內(nèi)存的大量消耗等一些列的問題。



但是盡管有這么多問題,我們依然要使用多線程編程,這樣才能充分利用多處理器的優(yōu)勢(shì)提升響應(yīng)效率,以保證應(yīng)用程序的相應(yīng)性能。相對(duì)于避免使用多線程編程來說,我們開發(fā)者更需要做的是掌握怎樣在開發(fā)過程中避免上述問題的發(fā)生。我們可以對(duì)重要數(shù)據(jù)的讀取加鎖,使用過程中避免兩個(gè)或多個(gè)線程相互等待,對(duì)數(shù)據(jù)或資源加鎖要避免低優(yōu)先級(jí)卡頓高優(yōu)先級(jí)任務(wù)的執(zhí)行,避免創(chuàng)建過多無用的線程,等等解決辦法,但是因噎廢食,并不可取。
Q&A
一個(gè)復(fù)雜的計(jì)算應(yīng)該用進(jìn)程還是線程?
從上述介紹可知,如果你的這次復(fù)雜計(jì)算是你要執(zhí)行的整個(gè)活動(dòng),那么它本身可以算的上是一個(gè)進(jìn)程的概念,但是實(shí)際上計(jì)算真正執(zhí)行時(shí)是依靠進(jìn)程進(jìn)行CPU調(diào)度和分派后獲取的線程去執(zhí)行的。對(duì)于復(fù)雜的計(jì)算來說,其特性就在于復(fù)雜二字,如果你想要這個(gè)復(fù)雜的計(jì)算流程對(duì)主線程干擾降到最低,那么你可以開辟后臺(tái)線程去執(zhí)行,獲得執(zhí)行結(jié)果后再回到主線程做你要做的事情。這也是并發(fā)處理的意義所在:保證整個(gè)進(jìn)程流暢和對(duì)多處理器的高效利用。