首頁 > 軟體

深入解析Python中的多程序

2022-06-20 22:00:47

前言

現在我們的計算機都是多個核的,通俗來說就是多個處理或者計算單元。為了加快運算和處理速度,我們可以將不同的任務交給多個核心進行同時處理,從而提高了運算速度和效率,多個核心同時運作就是多個程序同時進行,這就是多程序。

1.建立程序

建立程序和建立執行緒的方法基本一致,請看下面程式碼:

# coding:utf-8
# 匯入多程序的包,並重新命名為mp
import multiprocessing as mp
# 主要工作
def p1():
    print("zxy")
if __name__ == "__main__":
    # 建立新程序
    new_process = mp.Process(target=p1, name="p1")
    # 啟動這個程序
    new_process.start()
    # 阻塞該程序
    new_process.join()

控制檯效果圖:

2.多程序中的Queue

為什麼要在多程序中使用queue呢?
因為多程序和多執行緒一樣,在工作函數中,無法通過return返回程序函數中的結果,所以使用queue進行儲存結果,要用的時候再進行取出。

# coding:utf-8
import time
import multiprocessing as mp
"""
    使用多程序時,執行程式所用的時間
"""
def job1(q):
    res = 0
    for i in range(100):
        res += i + i**5 +i**8
        time.sleep(0.1)
    # 將結果放入佇列中
    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()
    # 建立佇列
    q = mp.Queue()
    # 建立程序1
    process1 = mp.Process(target=job1, args=(q,))
    # 建立程序2
    process2 = mp.Process(target=job2, args=(q,))
    process1.start()
    process2.start()
    # 通過佇列獲取值
    res1 = q.get()
    res2 = q.get()
    print("res1為%d,res2為%d" % (res1, res2))
    end_time = time.time()
    print("整個過程所用時間為%s" %(end_time-start_time))

效果圖:

3.多程序與多執行緒的效能比較

接下來使用多程序、多執行緒、以及什麼都不用的普通方法進行處理,看看他們三種方法的效率如何?

# coding:utf-8
import multiprocessing as mp
import time
import threading as th
"""
    多程序、多執行緒、普通方法的效能比較
"""
# 多程序工作
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("多程序使用時間為", (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
    # 進行兩次
    normal_job(normal_sum)
    normal_job(normal_sum)
    normal_end = time.time()
    print("普通方法使用的時間是", (normal_end-normal_start))

效果圖:

實驗結果表明:多程序的效率確實高!!!

4.程序池pool

程序池是幹什麼用的呢?
程序池就是python的多程序提供的一個池子,將所有的程序都放在這個池子裡面,讓計算機自己去使用程序池中的資源,從而多程序處理一些程式,進而提高工作效率。

(1)預設使用程序池中全部程序時

# coding:utf-8
import time
import multiprocessing as mp
"""
    程序池pool的使用
"""
def job(num):
    time.sleep(1)
    return num * num
if __name__ == "__main__":
    start_time = time.time()
    # 括號裡面不加引數時,預設使用程序池中所有程序
    pool = mp.Pool()
    res = pool.map(job, range(10))
    print(res)
    end_time = time.time()
    print("執行時間為", (end_time-start_time))

效果圖:

(2)指定程序池中程序數時

# coding:utf-8
import time
import multiprocessing as mp
"""
    程序池pool的使用
"""
def job(num):
    time.sleep(1)
    return num * num
if __name__ == "__main__":
    start_time = time.time()
    # 括號裡面加引數時,指定兩個程序進行處理
    pool = mp.Pool(processes=2)
    res = pool.map(job, range(10))
    print(res)
    end_time = time.time()
    print("執行時間為", (end_time-start_time))

效果圖:

(3)不使用多程序時

# 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("不使用程序池所用時間為", (end_time-start_time))

效果圖:

實驗結論:多程序處理事情,效率很高!!!核心越多,處理越快!

5.共用記憶體

一個核心,我們多執行緒處理時,可以使用全域性變數來共用資料。但是多程序之間是不行的,那我們多程序之間應該如何共用資料呢?
那就得用到共用記憶體了!

# coding:utf-8
import multiprocessing as mp
"""
    共用記憶體
"""
if __name__ == "__main__":
    # 第一個引數是資料型別的程式碼,i代表整數型別
    # 第二個引數是共用資料的值
    v = mp.Value("i", 0)

6.程序鎖lock

程序鎖和執行緒鎖的用法基本一致。程序鎖的誕生是為了避免多程序之間搶佔共用資料,進而造成多程序之間混亂修改共用記憶體的局面。

(1)不加鎖之前

# coding:utf-8
import multiprocessing as mp
import time
"""
    程序中的鎖lock
"""
def job(v, num):
    for i in range(10):
        v.value += num
        print(v.value)
        time.sleep(0.2)
if __name__ == "__main__":
    # 多程序中的共用記憶體
    v = mp.Value("i", 0)
    # 程序1讓共用變數每次加1
    process1 = mp.Process(target=job, args=(v, 1))
    # 程序2讓共用變數每次加3
    process2 = mp.Process(target=job, args=(v, 3))
    process1.start()
    process2.start()

效果圖:

(2)加鎖之後

# coding:utf-8
import multiprocessing as mp
import time
"""
    程序中的鎖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__":
    # 建立程序鎖
    l = mp.Lock()
    # 多程序中的共用記憶體
    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()

效果圖:

到此這篇關於深入解析Python中的多程序的文章就介紹到這了,更多相關Python多程序內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com