深入解析Python中的多進(jìn)程
前言
現(xiàn)在我們的計(jì)算機(jī)都是多個(gè)核的,通俗來說就是多個(gè)處理或者計(jì)算單元。為了加快運(yùn)算和處理速度,我們可以將不同的任務(wù)交給多個(gè)核心進(jìn)行同時(shí)處理,從而提高了運(yùn)算速度和效率,多個(gè)核心同時(shí)運(yùn)作就是多個(gè)進(jìn)程同時(shí)進(jìn)行,這就是多進(jìn)程。
1.創(chuàng)建進(jìn)程
創(chuàng)建進(jìn)程和創(chuàng)建線程的方法基本一致,請(qǐng)看下面代碼:
# coding:utf-8 # 導(dǎo)入多進(jìn)程的包,并重命名為mp import multiprocessing as mp # 主要工作 def p1(): print("zxy") if __name__ == "__main__": # 創(chuàng)建新進(jìn)程 new_process = mp.Process(target=p1, name="p1") # 啟動(dòng)這個(gè)進(jìn)程 new_process.start() # 阻塞該進(jìn)程 new_process.join()
控制臺(tái)效果圖:
2.多進(jìn)程中的Queue
為什么要在多進(jìn)程中使用queue呢?
因?yàn)槎噙M(jìn)程和多線程一樣,在工作函數(shù)中,無法通過return返回進(jìn)程函數(shù)中的結(jié)果,所以使用queue進(jìn)行存儲(chǔ)結(jié)果,要用的時(shí)候再進(jìn)行取出。
# coding:utf-8 import time import multiprocessing as mp """ 使用多進(jìn)程時(shí),運(yùn)行程序所用的時(shí)間 """ def job1(q): res = 0 for i in range(100): res += i + i**5 +i**8 time.sleep(0.1) # 將結(jié)果放入隊(duì)列中 q.put(res) def job2(q): res = 0 for i in range(100): res += i + i**5 +i**8 time.sleep(0.1) q.put(res) if __name__ == "__main__": start_time = time.time() # 創(chuàng)建隊(duì)列 q = mp.Queue() # 創(chuàng)建進(jìn)程1 process1 = mp.Process(target=job1, args=(q,)) # 創(chuàng)建進(jìn)程2 process2 = mp.Process(target=job2, args=(q,)) process1.start() process2.start() # 通過隊(duì)列獲取值 res1 = q.get() res2 = q.get() print("res1為%d,res2為%d" % (res1, res2)) end_time = time.time() print("整個(gè)過程所用時(shí)間為%s" %(end_time-start_time))
效果圖:
3.多進(jìn)程與多線程的性能比較
接下來使用多進(jìn)程、多線程、以及什么都不用的普通方法進(jìn)行處理,看看他們?nèi)N方法的效率如何?
# coding:utf-8 import multiprocessing as mp import time import threading as th """ 多進(jìn)程、多線程、普通方法的性能比較 """ # 多進(jìn)程工作 def mp_job(res): for i in range(10000000): res += i**5 + i**6 print(res) # 多線程工作 def mt_job(res): for i in range(10000000): res += i**5 + i**6 print(res) # 普通方法工作 def normal_job(res): for i in range(10000000): res += i ** 5 + i ** 6 print(res) if __name__ == "__main__": mp_sum = 0 mp_start = time.time() process1 =mp.Process(target=mp_job, args=(mp_sum, )) process2 = mp.Process(target=mp_job, args=(mp_sum,)) process1.start() process2.start() process1.join() process2.join() mp_end = time.time() print("多進(jìn)程使用時(shí)間為", (mp_end-mp_start)) mt_start = time.time() mt_sum = 0 thread1 = th.Thread(target=mt_job, args=(mt_sum, )) thread2 = th.Thread(target=mt_job, args=(mt_sum, )) thread1.start() thread2.start() thread1.join() thread2.join() mt_end = time.time() print("多線程使用的時(shí)間是", (mt_end-mt_start)) normal_start = time.time() normal_sum = 0 # 進(jìn)行兩次 normal_job(normal_sum) normal_job(normal_sum) normal_end = time.time() print("普通方法使用的時(shí)間是", (normal_end-normal_start))
效果圖:
實(shí)驗(yàn)結(jié)果表明:多進(jìn)程的效率確實(shí)高?。。?/p>
4.進(jìn)程池pool
進(jìn)程池是干什么用的呢?
進(jìn)程池就是python的多進(jìn)程提供的一個(gè)池子,將所有的進(jìn)程都放在這個(gè)池子里面,讓計(jì)算機(jī)自己去使用進(jìn)程池中的資源,從而多進(jìn)程處理一些程序,進(jìn)而提高工作效率。
(1)默認(rèn)使用進(jìn)程池中全部進(jìn)程時(shí)
# coding:utf-8 import time import multiprocessing as mp """ 進(jìn)程池pool的使用 """ def job(num): time.sleep(1) return num * num if __name__ == "__main__": start_time = time.time() # 括號(hào)里面不加參數(shù)時(shí),默認(rèn)使用進(jìn)程池中所有進(jìn)程 pool = mp.Pool() res = pool.map(job, range(10)) print(res) end_time = time.time() print("運(yùn)行時(shí)間為", (end_time-start_time))
效果圖:
(2)指定進(jìn)程池中進(jìn)程數(shù)時(shí)
# coding:utf-8 import time import multiprocessing as mp """ 進(jìn)程池pool的使用 """ def job(num): time.sleep(1) return num * num if __name__ == "__main__": start_time = time.time() # 括號(hào)里面加參數(shù)時(shí),指定兩個(gè)進(jìn)程進(jìn)行處理 pool = mp.Pool(processes=2) res = pool.map(job, range(10)) print(res) end_time = time.time() print("運(yùn)行時(shí)間為", (end_time-start_time))
效果圖:
(3)不使用多進(jìn)程時(shí)
# coding:utf-8 import time def job(res): for i in range(10): res.append(i*i) time.sleep(1) if __name__ == "__main__": start_time = time.time() res = [] job(res) print(res) end_time =time.time() print("不使用進(jìn)程池所用時(shí)間為", (end_time-start_time))
效果圖:
實(shí)驗(yàn)結(jié)論:多進(jìn)程處理事情,效率很高?。?!核心越多,處理越快!
5.共享內(nèi)存
一個(gè)核心,我們多線程處理時(shí),可以使用全局變量來共享數(shù)據(jù)。但是多進(jìn)程之間是不行的,那我們多進(jìn)程之間應(yīng)該如何共享數(shù)據(jù)呢?
那就得用到共享內(nèi)存了!
# coding:utf-8 import multiprocessing as mp """ 共享內(nèi)存 """ if __name__ == "__main__": # 第一個(gè)參數(shù)是數(shù)據(jù)類型的代碼,i代表整數(shù)類型 # 第二個(gè)參數(shù)是共享數(shù)據(jù)的值 v = mp.Value("i", 0)
6.進(jìn)程鎖lock
進(jìn)程鎖和線程鎖的用法基本一致。進(jìn)程鎖的誕生是為了避免多進(jìn)程之間搶占共享數(shù)據(jù),進(jìn)而造成多進(jìn)程之間混亂修改共享內(nèi)存的局面。
(1)不加鎖之前
# coding:utf-8 import multiprocessing as mp import time """ 進(jìn)程中的鎖lock """ def job(v, num): for i in range(10): v.value += num print(v.value) time.sleep(0.2) if __name__ == "__main__": # 多進(jìn)程中的共享內(nèi)存 v = mp.Value("i", 0) # 進(jìn)程1讓共享變量每次加1 process1 = mp.Process(target=job, args=(v, 1)) # 進(jìn)程2讓共享變量每次加3 process2 = mp.Process(target=job, args=(v, 3)) process1.start() process2.start()
效果圖:
(2)加鎖之后
# coding:utf-8 import multiprocessing as mp import time """ 進(jìn)程中的鎖lock """ def job(v, num, l): # 加鎖 l.acquire() for i in range(10): v.value += num print(v.value) time.sleep(0.2) # 解鎖 l.release() if __name__ == "__main__": # 創(chuàng)建進(jìn)程鎖 l = mp.Lock() # 多進(jìn)程中的共享內(nèi)存 v = mp.Value("i", 0) process1 = mp.Process(target=job, args=(v, 1, l)) process2 = mp.Process(target=job, args=(v, 3, l)) process1.start() process2.start()
效果圖:
到此這篇關(guān)于深入解析Python中的多進(jìn)程的文章就介紹到這了,更多相關(guān)Python多進(jìn)程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
表格梳理python內(nèi)置數(shù)學(xué)模塊math分析詳解
這篇文章主要為大家介紹了python內(nèi)置數(shù)學(xué)模塊math的分析詳解,文中通過表格梳理的方式以便讓大家在學(xué)習(xí)過程中一目望去清晰明了,有需要的朋友可以借鑒參考下2021-10-10Django框架模板語言實(shí)例小結(jié)【變量,標(biāo)簽,過濾器,繼承,html轉(zhuǎn)義】
這篇文章主要介紹了Django框架模板語言,結(jié)合實(shí)例形式總結(jié)分析了Django框架中變量,標(biāo)簽,過濾器,繼承,html轉(zhuǎn)義等相關(guān)模板語言操作技巧,需要的朋友可以參考下2019-05-05使用Termux在手機(jī)上運(yùn)行Python的詳細(xì)過程
這篇文章主要介紹了使用Termux在手機(jī)上運(yùn)行Python的詳細(xì)過程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-10-10python logging 重復(fù)寫日志問題解決辦法詳解
這篇文章主要介紹了python logging 重復(fù)寫日志問題解決辦法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08簡單實(shí)現(xiàn)python數(shù)獨(dú)游戲
這篇文章主要為大家詳細(xì)介紹了如何簡單實(shí)現(xiàn)python數(shù)獨(dú)游戲,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03python函數(shù)指定默認(rèn)值的實(shí)例講解
在本篇內(nèi)容里小編給大家整理了一篇關(guān)于python函數(shù)指定默認(rèn)值的實(shí)例講解內(nèi)容,有需要的朋友們可以跟著學(xué)習(xí)參考下。2021-03-03Python?opencv進(jìn)行圓形識(shí)別(圓檢測)實(shí)例代碼
最近工作的項(xiàng)目上需要檢測圖像中是否有圓形,下面這篇文章主要給大家介紹了關(guān)于Python?opencv進(jìn)行圓形識(shí)別(圓檢測)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05