Python進(jìn)程和線程
學(xué)習(xí)目標(biāo)
1、了解多任務(wù)的概念
2、了解進(jìn)程的概念以及多進(jìn)程的作用
3、掌握多進(jìn)程完成多任務(wù)的工作原理及案例編寫
4、掌握進(jìn)程編號(hào)的獲取方式以及進(jìn)程使用的注意事項(xiàng)
5、了解線程的概念以及多線程的作用
6、掌握多進(jìn)程完成多任務(wù)的工作原理及案例編寫
一、多任務(wù)的概念
1、舉個(gè)栗子

思考:我們?cè)谑褂镁W(wǎng)盤下載資料的時(shí)候,為什么要多個(gè)任務(wù)同時(shí)下載呢? 答:多個(gè)任務(wù)同時(shí)執(zhí)行可以大大提高程序的執(zhí)行效率
2、提出問(wèn)題
問(wèn)題:利用我們目前所學(xué)的技術(shù),我們能否實(shí)現(xiàn)多任務(wù)操作呢? 答:不能,因?yàn)橹八鶎懙某绦蚨际菃稳蝿?wù)的,也就是說(shuō)一個(gè)函數(shù)或者方法執(zhí)行完成 , 另外一個(gè)函數(shù)或者方法才能執(zhí)行。要想實(shí)現(xiàn)多個(gè)任務(wù)同時(shí)執(zhí)行就需要使用多任務(wù)。多任務(wù)的最大好處是充分利用CPU資源,提高程序的執(zhí)行效率。
3、什么是多任務(wù)
多任務(wù)是指在同一時(shí)間內(nèi)執(zhí)行多個(gè)任務(wù)。 例如: 現(xiàn)在電腦安裝的操作系統(tǒng)都是多任務(wù)操作系統(tǒng),可以同時(shí)運(yùn)行著多個(gè)軟件。

4、多任務(wù)的兩種表現(xiàn)形式
① 并發(fā) ② 并行
5、并發(fā)操作
并發(fā):在一段時(shí)間內(nèi)交替去執(zhí)行多個(gè)任務(wù)。 例如:對(duì)于單核cpu處理多任務(wù),操作系統(tǒng)輪流讓各個(gè)任務(wù)交替執(zhí)行,假如:軟件1執(zhí)行0.01秒,切換到軟件2,軟件2執(zhí)行0.01秒,再切換到軟件3,執(zhí)行0.01秒……這樣反復(fù)執(zhí)行下去, 實(shí)際上每個(gè)軟件都是交替執(zhí)行的 。但是,由于CPU的執(zhí)行速度實(shí)在是太快了,表面上我們感覺(jué)就像這些軟件都在同時(shí)執(zhí)行一樣,這里需要注意單核cpu是并發(fā)的執(zhí)行多任務(wù)的。

6、并行操作
并行:在一段時(shí)間內(nèi)真正的同時(shí)一起執(zhí)行多個(gè)任務(wù)。 對(duì)于多核cpu處理多任務(wù),操作系統(tǒng)會(huì)給cpu的每個(gè)內(nèi)核安排一個(gè)執(zhí)行的任務(wù),多個(gè)內(nèi)核是真正的一起同時(shí)執(zhí)行多個(gè)任務(wù)。這里需要注意多核cpu是并行的執(zhí)行多任務(wù),始終有多個(gè)任務(wù)一起執(zhí)行。

二、進(jìn)程的概念
1、程序中實(shí)現(xiàn)多任務(wù)的方式
在Python中,想要實(shí)現(xiàn)多任務(wù)可以使用多進(jìn)程來(lái)完成。
2、進(jìn)程的概念
進(jìn)程(Process)是資源分配的最小單位,它是操作系統(tǒng)進(jìn)行資源分配和調(diào)度運(yùn)行的基本單位,通俗理解:一個(gè)正在運(yùn)行的程序就是一個(gè)進(jìn)程。 例如:正在運(yùn)行的qq , 微信等 他們都是一個(gè)進(jìn)程。

注: 一個(gè)程序運(yùn)行后至少有一個(gè)進(jìn)程
3、多進(jìn)程的作用
☆ 未使用多進(jìn)程

思考: 圖中是一個(gè)非常簡(jiǎn)單的程序 , 一旦運(yùn)行hello.py這個(gè)程序 , 按照代碼的執(zhí)行順序 , func_a函數(shù)執(zhí)行完畢后才能執(zhí)行func_b函數(shù) . 如果可以讓func_a和func_b同時(shí)運(yùn)行 , 顯然執(zhí)行hello.py這個(gè)程序的效率會(huì)大大提升 .

☆ 使用了多進(jìn)程

三、多進(jìn)程完成多任務(wù)
1、多進(jìn)程完成多任務(wù)
2、通過(guò)進(jìn)程類創(chuàng)建進(jìn)程對(duì)象
參數(shù)說(shuō)明:

3、進(jìn)程創(chuàng)建與啟動(dòng)的代碼
邊聽音樂(lè)邊敲代碼:
運(yùn)行結(jié)果:
這是一個(gè)使用Python multiprocessing模塊實(shí)現(xiàn)并行任務(wù)的代碼。代碼中定義了兩個(gè)函數(shù)music()和coding(),分別表示聽音樂(lè)和敲代碼這兩個(gè)任務(wù),每個(gè)任務(wù)都會(huì)執(zhí)行3次,且每次執(zhí)行后都會(huì)暫停0.2秒。代碼通過(guò)multiprocessing.Process()方法創(chuàng)建了兩個(gè)進(jìn)程music_process和coding_process,每個(gè)進(jìn)程都指定了一個(gè)target參數(shù),即對(duì)應(yīng)的任務(wù)music或coding。接著通過(guò)start()方法啟動(dòng)了這兩個(gè)進(jìn)程,它們會(huì)異步的同時(shí)執(zhí)行。if name == 'main':這一行是Python程序入口,用來(lái)保證在多進(jìn)程環(huán)境中不會(huì)重復(fù)啟動(dòng)進(jìn)程。 執(zhí)行該代碼后,會(huì)看到兩個(gè)進(jìn)程并行執(zhí)行各自的任務(wù),即打印“聽音樂(lè)…”和“敲代碼…”。
4、進(jìn)程執(zhí)行帶有參數(shù)的任務(wù)
參數(shù)說(shuō)明: 這是Python中的一個(gè)函數(shù),用于創(chuàng)建一個(gè)進(jìn)程對(duì)象并啟動(dòng)一個(gè)新的進(jìn)程。它的參數(shù)包括:
group:指定進(jìn)程組,通常不需要使用,默認(rèn)為None。
target:指定進(jìn)程啟動(dòng)時(shí)要執(zhí)行的函數(shù)。必須是可調(diào)用的對(duì)象。
name:指定進(jìn)程的名稱,通常不需要使用,默認(rèn)為None。
args:指定傳遞給目標(biāo)函數(shù)的參數(shù)元組。args=(1,2,'anne',)
kwargs:指定傳遞給目標(biāo)函數(shù)的關(guān)鍵字參數(shù)字典。kwargs={'name':'anne','age':18}
案例:args參數(shù)和kwargs參數(shù)的使用
加入join()方法是為了保證主進(jìn)程在所有子進(jìn)程執(zhí)行完畢后再結(jié)束,否則主進(jìn)程會(huì)在子進(jìn)程還沒(méi)執(zhí)行完畢就結(jié)束了。
在多進(jìn)程編程中,子進(jìn)程的執(zhí)行是異步的,主進(jìn)程和子進(jìn)程是并發(fā)執(zhí)行的,如果主進(jìn)程沒(méi)有等待子進(jìn)程執(zhí)行完畢就結(jié)束了,那么子進(jìn)程可能會(huì)被強(qiáng)制終止,導(dǎo)致程序出現(xiàn)異?;蛘邤?shù)據(jù)丟失等問(wèn)題。
因此,在啟動(dòng)子進(jìn)程后,應(yīng)該調(diào)用join()方法等待子進(jìn)程執(zhí)行完畢后再結(jié)束主進(jìn)程,以保證程序的正常運(yùn)行。join()方法會(huì)阻塞主進(jìn)程,直到所有的子進(jìn)程都執(zhí)行完畢后才會(huì)繼續(xù)執(zhí)行主進(jìn)程。?
案例:多個(gè)參數(shù)傳遞
運(yùn)行結(jié)果:
這段代碼實(shí)現(xiàn)了多進(jìn)程并發(fā)執(zhí)行不同任務(wù)的示例。具體實(shí)現(xiàn)如下:
1. 導(dǎo)入了multiprocessing和time模塊。
2. 定義了兩個(gè)函數(shù):music()和coding()。music()函數(shù)通過(guò)循環(huán)執(zhí)行num次輸出字符串name和“聽音樂(lè)...”字符串并sleep 0.2秒,模擬“聽音樂(lè)”任務(wù)。coding()函數(shù)通過(guò)循環(huán)執(zhí)行count次輸出“敲代碼...”字符串并sleep0.2秒,模擬“敲代碼”任務(wù)。
3. 在程序主入口中執(zhí)行兩個(gè)子進(jìn)程:music_process和coding_process。其中music_process進(jìn)程調(diào)用music()函數(shù),傳入?yún)?shù)num=3和name='多任務(wù)開始',coding_process進(jìn)程調(diào)用coding()函數(shù),傳入?yún)?shù)count=3。
4. 啟動(dòng)music_process和coding_process進(jìn)程。
5. 進(jìn)程開始并發(fā)執(zhí)行,其中music_process進(jìn)程輸出num次name和“聽音樂(lè)...”字符串,coding_process進(jìn)程輸出count次“敲代碼...”字符串。每次輸出之后程序會(huì)sleep 0.2秒,以模擬不同的任務(wù)執(zhí)行。 6. 進(jìn)程執(zhí)行完畢后程序結(jié)束。
四、獲取進(jìn)程編號(hào)
1、進(jìn)程編號(hào)的作用
當(dāng)程序中進(jìn)程的數(shù)量越來(lái)越多時(shí) , 如果沒(méi)有辦法區(qū)分主進(jìn)程和子進(jìn)程還有不同的子進(jìn)程 , 那么就無(wú)法進(jìn)行有效的進(jìn)程管理 , 為了方便管理實(shí)際上每個(gè)進(jìn)程都是有自己編號(hào)的。
2、兩種進(jìn)程編號(hào)
① 獲取當(dāng)前進(jìn)程編號(hào)
② 獲取當(dāng)前進(jìn)程的父進(jìn)程ppid = parent pid
3、獲取當(dāng)前進(jìn)程編號(hào)
案例:獲取子進(jìn)程編號(hào)
運(yùn)行結(jié)果:
這是一個(gè)使用Python的multiprocessing模塊創(chuàng)建多進(jìn)程的例子。
首先,定義了兩個(gè)函數(shù):music和coding,分別輸出進(jìn)程ID,然后使用for循環(huán)和time.sleep語(yǔ)句模擬耗時(shí)操作。
其次,在程序的主程序中,使用multiprocessing.Process創(chuàng)建了兩個(gè)進(jìn)程music_process和coding_process,分別使用target參數(shù)指定要執(zhí)行的函數(shù),以及args或kwargs參數(shù)將要執(zhí)行函數(shù)的參數(shù)傳遞進(jìn)去。然后調(diào)用start方法啟動(dòng)這兩個(gè)進(jìn)程,從而在兩個(gè)進(jìn)程中同時(shí)執(zhí)行不同的任務(wù)。
需要注意的是,使用if name == 'main' 是為了防止子進(jìn)程遞歸創(chuàng)建子進(jìn)程導(dǎo)致的一系列問(wèn)題,因?yàn)樵赪indows系統(tǒng)下,所有的Python程序都會(huì)自動(dòng)運(yùn)行一遍,而在Linux/MacOS系統(tǒng)下則不會(huì)。?
案例:獲取父進(jìn)程與子進(jìn)程編號(hào)
運(yùn)行結(jié)果:
這段代碼使用Python的multiprocessing模塊創(chuàng)建了兩個(gè)進(jìn)程來(lái)模擬聽音樂(lè)和編寫代碼兩個(gè)任務(wù)的同時(shí)執(zhí)行。
首先定義了兩個(gè)函數(shù)music()和coding()分別用于在進(jìn)程中執(zhí)行聽音樂(lè)和編寫代碼的任務(wù)。在函數(shù)中使用了os.getpid()和os.getppid()獲取當(dāng)前進(jìn)程和父進(jìn)程的ID。
在代碼中使用了 multiprocessing.Process() ?函數(shù)來(lái)創(chuàng)建兩個(gè)進(jìn)程。 music_process進(jìn)程執(zhí)行 music() 函數(shù),而 coding_process 進(jìn)程執(zhí)行 coding() 函數(shù)。
最后,在主進(jìn)程中使用 .start()方法啟動(dòng)兩個(gè)子進(jìn)程的執(zhí)行,觀察運(yùn)行結(jié)果可以發(fā)現(xiàn),music() 和 coding() 函數(shù)的任務(wù)在兩個(gè)子進(jìn)程中并行執(zhí)行。
五、進(jìn)程應(yīng)用注意點(diǎn)
1、進(jìn)程間不共享全局變量
實(shí)際上創(chuàng)建一個(gè)子進(jìn)程就是把主進(jìn)程的資源進(jìn)行拷貝產(chǎn)生了一個(gè)新的進(jìn)程,這里的主進(jìn)程和子進(jìn)程是互相獨(dú)立的。

案例:
原理分析:

三個(gè)進(jìn)程分別操作的都是自己進(jìn)程里面的全局變量my_list, 不會(huì)對(duì)其它進(jìn)程里面的全局變量產(chǎn)生影響,所以進(jìn)程之間不共享全局變量,只不過(guò)進(jìn)程之間的全局變量名字相同而已,但是操作的不是同一個(gè)進(jìn)程里面的全局變量。
知識(shí)點(diǎn)小結(jié): 創(chuàng)建子進(jìn)程會(huì)對(duì)主進(jìn)程資源進(jìn)行拷貝,也就是說(shuō)子進(jìn)程是主進(jìn)程的一個(gè)副本,好比是一對(duì)雙胞胎,之所以進(jìn)程之間不共享全局變量,是因?yàn)椴僮鞯牟皇峭粋€(gè)進(jìn)程里面的全局變量,只不過(guò)不同進(jìn)程里面的全局變量名字相同而已。
2、主進(jìn)程與子進(jìn)程的結(jié)束順序

編輯切換為居中
代碼演示:
執(zhí)行結(jié)果:

這段代碼使用了Python的multiprocessing模塊來(lái)創(chuàng)建并啟動(dòng)一個(gè)子進(jìn)程,同時(shí)在主進(jìn)程中延遲1秒后輸出一條信息。 具體解釋如下:
導(dǎo)入multiprocessing和time模塊。
定義一個(gè)名為work的函數(shù),函數(shù)內(nèi)部使用for循環(huán)和time.sleep()函數(shù)模擬一些耗時(shí)的工作。
在if name == 'main':語(yǔ)句塊中,創(chuàng)建一個(gè)名為work_process的子進(jìn)程,該進(jìn)程的目標(biāo)函數(shù)為work。
啟動(dòng)子進(jìn)程,調(diào)用work_process.start()。
使用time.sleep(1)函數(shù)在主進(jìn)程中延遲1秒。
輸出一條信息,表示主進(jìn)程執(zhí)行完畢。
因?yàn)樽舆M(jìn)程和主進(jìn)程是并行執(zhí)行的,所以在主進(jìn)程延遲1秒后,子進(jìn)程仍然在執(zhí)行工作函數(shù)中的任務(wù)。因此,輸出的信息可能會(huì)在子進(jìn)程的輸出信息之前或之后,具體取決于操作系統(tǒng)的調(diào)度策略
☆ 解決方案一:設(shè)置守護(hù)進(jìn)程
運(yùn)行結(jié)果:
這段代碼使用了Python的multiprocessing模塊,實(shí)現(xiàn)了創(chuàng)建一個(gè)子進(jìn)程并在其中執(zhí)行一個(gè)工作函數(shù)。
首先定義了一個(gè)工作函數(shù)work(),該函數(shù)會(huì)循環(huán)執(zhí)行10次,每次輸出“工作中...”,并睡眠0.2秒。 在主程序中,首先創(chuàng)建了一個(gè)子進(jìn)程work_process,將work函數(shù)作為其target參數(shù)傳遞進(jìn)去,表示該子進(jìn)程需要執(zhí)行work函數(shù)。
然后將work_process的daemon屬性設(shè)置為True,表示該子進(jìn)程是守護(hù)進(jìn)程,即當(dāng)主進(jìn)程退出時(shí),該子進(jìn)程也會(huì)隨之退出,不再執(zhí)行子進(jìn)程中的代碼。 接下來(lái)啟動(dòng)子進(jìn)程work_process,子進(jìn)程開始執(zhí)行work函數(shù)中的代碼。
主進(jìn)程延遲1秒后,輸出“主進(jìn)程執(zhí)行完畢”,然后退出。 由于子進(jìn)程是守護(hù)進(jìn)程,隨著主進(jìn)程的退出,子進(jìn)程也會(huì)被銷毀,不再執(zhí)行work函數(shù)中的代碼。
☆ 解決方案二:銷毀子進(jìn)程
提示: 以上兩種方式都能保證主進(jìn)程退出子進(jìn)程銷毀
運(yùn)行結(jié)果:
這段代碼使用了Python的multiprocessing模塊,實(shí)現(xiàn)了創(chuàng)建一個(gè)子進(jìn)程,讓子進(jìn)程執(zhí)行一個(gè)工作函數(shù)work(),并在主進(jìn)程中控制子進(jìn)程的運(yùn)行和終止。 具體解釋如下:
導(dǎo)入multiprocessing和time模塊。
定義一個(gè)工作函數(shù)work(),該函數(shù)會(huì)循環(huán)執(zhí)行10次,每次打印一條信息“工作中...”,并休眠0.2秒。
在if name == 'main'條件語(yǔ)句中,創(chuàng)建一個(gè)子進(jìn)程work_process,它的目標(biāo)函數(shù)是work()。
啟動(dòng)子進(jìn)程work_process,它會(huì)開始執(zhí)行work()函數(shù)中的循環(huán)語(yǔ)句。
主進(jìn)程延遲1秒,等待子進(jìn)程執(zhí)行一段時(shí)間。
調(diào)用work_process.terminate()方法,強(qiáng)制終止子進(jìn)程的執(zhí)行。
打印出“主進(jìn)程執(zhí)行完畢”信息。
總體來(lái)說(shuō),這段代碼展示了如何在Python中使用multiprocessing模塊創(chuàng)建和控制子進(jìn)程的運(yùn)行和終止。
六、線程的概念
1、線程的概念
在Python中,想要實(shí)現(xiàn)多任務(wù)還可以使用多線程來(lái)完成。
2、為什么使用多線程?
進(jìn)程是分配資源的最小單位 , 一旦創(chuàng)建一個(gè)進(jìn)程就會(huì)分配一定的資源 , 就像跟兩個(gè)人聊QQ就需要打開兩個(gè)QQ軟件一樣是比較浪費(fèi)資源的 . 線程是程序執(zhí)行的最小單位 , 實(shí)際上進(jìn)程只負(fù)責(zé)分配資源 , 而利用這些資源執(zhí)行程序的是線程 , 也就說(shuō)進(jìn)程是線程的容器 , 一個(gè)進(jìn)程中最少有一個(gè)線程來(lái)負(fù)責(zé)執(zhí)行程序 。同時(shí)線程自己不擁有系統(tǒng)資源,只需要一點(diǎn)兒在運(yùn)行中必不可少的資源,但它可與同屬一個(gè)進(jìn)程的其它線程共享進(jìn)程所擁有的全部資源 。這就像通過(guò)一個(gè)QQ軟件(一個(gè)進(jìn)程)打開兩個(gè)窗口(兩個(gè)線程)跟兩個(gè)人聊天一樣 , 實(shí)現(xiàn)多任務(wù)的同時(shí)也節(jié)省了資源。
3、多線程的作用
☆ 單線程執(zhí)行

☆ 多線程執(zhí)行

八、多線程完成多任務(wù)
1、多線程完成多任務(wù)

2、線程創(chuàng)建與啟動(dòng)代碼
單線程案例:
多線程案例:
3、線程執(zhí)行帶有參數(shù)的任務(wù)

在主線程中,通過(guò) music_thread.start() 和 coding_thread.start() 啟動(dòng)兩個(gè)線程,使它們可以同時(shí)運(yùn)行。由于線程是并發(fā)執(zhí)行的,因此 music() 和 coding() 函數(shù)會(huì)交替執(zhí)行,輸出相應(yīng)的信息。
4、主線程和子線程的結(jié)束順序
運(yùn)行結(jié)果:
這段代碼使用了 Python 的 threading 模塊,創(chuàng)建了一個(gè)線程 work_thread,執(zhí)行 work() 函數(shù)。 work() 函數(shù)會(huì)輸出 'work...',并且每次循環(huán)會(huì)暫停 0.2 秒,循環(huán)次數(shù)為 10。
在主線程中,通過(guò) work_thread.start() 啟動(dòng)線程,使它可以開始執(zhí)行。
接著,主線程會(huì)延時(shí) 1 秒鐘,然后輸出 '主線程執(zhí)行完畢'。由于 work_thread 線程需要 2 秒鐘才能完成全部工作,因此主線程先于 work_thread 線程執(zhí)行完畢。
通過(guò)使用線程,可以讓程序在多個(gè)任務(wù)之間切換執(zhí)行,提高程序的效率和響應(yīng)速度。
☆ 設(shè)置守護(hù)線程方式一
運(yùn)行結(jié)果:
這段代碼使用了Python的time和threading模塊。
首先定義了一個(gè)函數(shù)work(),用于在子線程中執(zhí)行任務(wù)。該函數(shù)循環(huán)10次,每次輸出字符串"work..." ,并使用time.sleep(0.2)來(lái)模擬任務(wù)執(zhí)行的時(shí)間。 接下來(lái),在主程序中,創(chuàng)建了一個(gè)子線程work_thread,并將work()函數(shù)作為其目標(biāo)函數(shù),設(shè)置了daemon=True以將其設(shè)置為守護(hù)線程。然后,使用work_thread.start()啟動(dòng)子線程。
接著,主線程使用time.sleep(1)延時(shí)1秒,以等待子線程執(zhí)行任務(wù)。最后,主線程輸出字符串"主線程執(zhí)行完畢"。 由于子線程被設(shè)置為守護(hù)線程,當(dāng)主線程執(zhí)行完畢后,子線程也會(huì)隨之結(jié)束。
因此,如果沒(méi)有設(shè)置守護(hù)線程,子線程將會(huì)一直執(zhí)行下去,直到任務(wù)完成或者被手動(dòng)停止。
☆ 設(shè)置守護(hù)線程方式二
運(yùn)行結(jié)果:
這段代碼使用了 Python 的 threading 模塊創(chuàng)建了一個(gè)子線程,并將其設(shè)置為守護(hù)主線程,然后啟動(dòng)了該子線程。子線程的工作是輸出 'work...' 字符串并休眠 0.2 秒,重復(fù)執(zhí)行 10 次。
在主線程中,代碼延時(shí) 1 秒后輸出 '主線程執(zhí)行完畢' 字符串。因?yàn)樽泳€程被設(shè)置為守護(hù)主線程,所以當(dāng)主線程執(zhí)行完畢后,子線程也會(huì)隨之結(jié)束。 如果沒(méi)有設(shè)置子線程為守護(hù)主線程,那么主線程執(zhí)行完畢后,子線程仍然會(huì)繼續(xù)執(zhí)行,直到完成所有工作。
5、線程間的執(zhí)行順序
思考:當(dāng)我們?cè)谶M(jìn)程中創(chuàng)建了多個(gè)線程,其線程之間是如何執(zhí)行的呢?按順序執(zhí)行?一起執(zhí)行?還是其他的執(zhí)行方式呢?

答:線程之間的執(zhí)行是無(wú)序的,驗(yàn)證
☆ 獲取當(dāng)前線程信息
# 通過(guò)current_thread方法獲取線程對(duì)象current_thread = threading.current_thread()# 通過(guò)current_thread對(duì)象可以知道線程的相關(guān)信息,例如被創(chuàng)建的順序print(current_thread)
☆ 線程間的執(zhí)行順序
總結(jié):線程之間執(zhí)行是無(wú)序的,是由CPU調(diào)度決定某個(gè)線程先執(zhí)行的。
6、線程間共享全局變量
☆ 線程間共享全局變量
多個(gè)線程都是在同一個(gè)進(jìn)程中 , 多個(gè)線程使用的資源都是同一個(gè)進(jìn)程中的資源 ,因此多線程間是共享全局變量

示例代碼:
運(yùn)行結(jié)果:
這是一個(gè)使用 Python 中的 threading 模塊進(jìn)行多線程編程的例子。
代碼定義了兩個(gè)函數(shù) write_data() 和 read_data(),分別實(shí)現(xiàn)向一個(gè)空列表 my_list 中添加數(shù)據(jù)和讀取列表中的數(shù)據(jù)。 代碼中還定義了兩個(gè)線程 write_thread 和 read_thread,分別用于執(zhí)行寫入數(shù)據(jù)和讀取數(shù)據(jù)這兩個(gè)任務(wù)。
程序的主函數(shù)中,首先將 write_thread 和 read_thread 分別指向 write_data() 和 read_data() 函數(shù),并調(diào)用 start() 啟動(dòng) write_thread 線程,等待 1 秒鐘后啟動(dòng) read_thread 線程。
在程序執(zhí)行時(shí),write_thread 和 read_thread 兩個(gè)線程將同時(shí)運(yùn)行,write_thread 將數(shù)據(jù)添加到 my_list 列表中,read_thread 讀取 my_list 列表并打印輸出,由于線程之間并沒(méi)有進(jìn)行同步操作,所以可能會(huì)出現(xiàn) race conditions,即寫入和讀取的順序不確定。
7、總結(jié):進(jìn)程和線程對(duì)比
☆ 關(guān)系對(duì)比
① 線程是依附在進(jìn)程里面的,沒(méi)有進(jìn)程就沒(méi)有線程。 ② 一個(gè)進(jìn)程默認(rèn)提供一條線程,進(jìn)程可以創(chuàng)建多個(gè)線程。

☆ 區(qū)別對(duì)比
① 進(jìn)程之間不共享全局變量
② 線程之間共享全局變量
③ 創(chuàng)建進(jìn)程的資源開銷要比創(chuàng)建線程的資源開銷要大
④ 進(jìn)程是操作系統(tǒng)資源分配的基本單位,線程是CPU調(diào)度的基本單位
☆ 優(yōu)缺點(diǎn)對(duì)比
① 進(jìn)程優(yōu)缺點(diǎn): 優(yōu)點(diǎn):可以用多核 缺點(diǎn):資源開銷大
② 線程優(yōu)缺點(diǎn) 優(yōu)點(diǎn):資源開銷小 缺點(diǎn):不能使用多核