深入解析Python中的多進(jìn)程
前言
現(xiàn)在我們的計算機(jī)都是多個核的,通俗來說就是多個處理或者計算單元。為了加快運(yùn)算和處理速度,我們可以將不同的任務(wù)交給多個核心進(jìn)行同時處理,從而提高了運(yùn)算速度和效率,多個核心同時運(yùn)作就是多個進(jìn)程同時進(jìn)行,這就是多進(jìn)程。
1.創(chuàng)建進(jìn)程
創(chuàng)建進(jìn)程和創(chuà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")
# 啟動這個進(jìn)程
new_process.start()
# 阻塞該進(jìn)程
new_process.join()控制臺效果圖:

2.多進(jìn)程中的Queue
為什么要在多進(jìn)程中使用queue呢?
因?yàn)槎噙M(jìn)程和多線程一樣,在工作函數(shù)中,無法通過return返回進(jìn)程函數(shù)中的結(jié)果,所以使用queue進(jìn)行存儲結(jié)果,要用的時候再進(jìn)行取出。
# coding:utf-8
import time
import multiprocessing as mp
"""
使用多進(jìn)程時,運(yùn)行程序所用的時間
"""
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("整個過程所用時間為%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)程使用時間為", (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("多線程使用的時間是", (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("普通方法使用的時間是", (normal_end-normal_start))效果圖:

實(shí)驗(yàn)結(jié)果表明:多進(jìn)程的效率確實(shí)高?。?!
4.進(jìn)程池pool
進(jìn)程池是干什么用的呢?
進(jìn)程池就是python的多進(jìn)程提供的一個池子,將所有的進(jìn)程都放在這個池子里面,讓計算機(jī)自己去使用進(jìn)程池中的資源,從而多進(jìn)程處理一些程序,進(jìn)而提高工作效率。
(1)默認(rèn)使用進(jìn)程池中全部進(jìn)程時
# 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()
# 括號里面不加參數(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)行時間為", (end_time-start_time))效果圖:

(2)指定進(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()
# 括號里面加參數(shù)時,指定兩個進(jìn)程進(jìn)行處理
pool = mp.Pool(processes=2)
res = pool.map(job, range(10))
print(res)
end_time = time.time()
print("運(yùn)行時間為", (end_time-start_time))效果圖:

(3)不使用多進(jìn)程時
# 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)程池所用時間為", (end_time-start_time))效果圖:

實(shí)驗(yàn)結(jié)論:多進(jìn)程處理事情,效率很高?。?!核心越多,處理越快!
5.共享內(nèi)存
一個核心,我們多線程處理時,可以使用全局變量來共享數(shù)據(jù)。但是多進(jìn)程之間是不行的,那我們多進(jìn)程之間應(yīng)該如何共享數(shù)據(jù)呢?
那就得用到共享內(nèi)存了!
# coding:utf-8
import multiprocessing as mp
"""
共享內(nèi)存
"""
if __name__ == "__main__":
# 第一個參數(shù)是數(shù)據(jù)類型的代碼,i代表整數(shù)類型
# 第二個參數(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
舉例講解Linux系統(tǒng)下Python調(diào)用系統(tǒng)Shell的方法
這篇文章主要介紹了舉例講解Linux系統(tǒng)下Python調(diào)用系統(tǒng)Shell的方法,包括用Python和shell讀取文件某一行的實(shí)例,需要的朋友可以參考下2015-11-11
python 實(shí)現(xiàn)"神經(jīng)衰弱"翻牌游戲
這篇文章主要介紹了python 實(shí)現(xiàn)"神經(jīng)衰弱"游戲,幫助大家更好的理解和使用python的pygame庫,感興趣的朋友可以了解下2020-11-11
Python-docx 實(shí)現(xiàn)整體修改或者部分修改文字的大小和字體類型
這篇文章主要介紹了Python-docx 實(shí)現(xiàn)整體修改或者部分修改文字的大小和字體類型,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03
python并發(fā)編程多進(jìn)程 互斥鎖原理解析
這篇文章主要介紹了python并發(fā)編程多進(jìn)程 互斥鎖原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-08-08
Python Pydantic數(shù)據(jù)驗(yàn)證的實(shí)現(xiàn)
本文主要介紹了Python Pydantic數(shù)據(jù)驗(yàn)證的實(shí)現(xiàn)2025-04-04
PyCharm如何設(shè)置新建文件默認(rèn)為LF換行符
這篇文章主要介紹了PyCharm如何設(shè)置新建文件默認(rèn)為LF換行符問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-03-03
Python OpenCV 圖像矯正的原理實(shí)現(xiàn)
這篇文章主要介紹了Python OpenCV 圖像矯正的原理實(shí)現(xiàn),檢測邊緣點(diǎn);以邊緣點(diǎn)作為輸入,采用Hough直線檢測,檢測出最多點(diǎn)共線的四條直線,更多相關(guān)內(nèi)容需要的朋友可以參考一下2022-07-07
Python 數(shù)據(jù)可視化之Seaborn詳解
這篇文章主要介紹了Python數(shù)據(jù)可視化庫seaborn的使用總結(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2021-11-11

