Python多進程

在Python中如果想創建多進程需要用到multiprrocessing中的Prrocess方法。

在進程之間全局變數是不共享的,如果要對進程的全局變數進行使用的話就需要用到multiprrocessing的Queue方法

首先我們先創建一個多進程

import time
from multiprocessing import Process
# 進程之間全局變數不共享


def work_1():
    for i in range(10):
        print('任務1')
        time.sleep(0.5)


def work_2():
    for i in range(10):
        print('任務2')
        time.sleep(0.5)


# 進程執行的時候不加main 為什麼會報錯:
# 在執行過程中相當於在另外一個py文件中導入這個模組並運行函數,由於是導入模組所以
# 創建多進程的程式碼也會被導入,然後就又去開了執行緒,陷入無限遞歸的狀態
if __name__ == '__main__':
    # 創建兩個進程
    p1 = Process(target=work_1)
    p2 = Process(target=work_2)
    p1.start()
    p2.start()

看過我之前寫的關於執行緒的那麼上面這段程式碼一定可以看懂,如果不明白可以回去看看關於執行緒的。

我們在多進程之間通訊需要用到隊列,但是這個隊列不是Queue.queue() 而是multiprrocessing中的Queue

queue.Queue 是進程內非阻塞隊列

multiprocessing.Queue 是跨進程通訊隊列


import requests
from multiprocessing import Process, Queue

def
work_1(q): while q.qsize() > 0: url = q.get() requests.get(url) print('任務1') def work_2(q): while q.qsize() > 0: url = q.get() requests.get(url) print('任務2') if __name__ == '__main__': q = Queue() for i in range(10): q.put('//localhost:3000/login') # 將q 這個實例化對象當作參數傳入函數中(不同的進程中),可以實現多進程共享變數,把這個隊列放到一個公共區間內 p1 = Process(target=work_1, args=(q,)) p2 = Process(target=work_2, args=(q,)) p1.start() p2.start()

下面來聊一聊進程池:

Pool可以提供指定數量的進程供用戶調用,當有新的請求提交到pool中時,如果池還沒有滿,那麼就會創建一個新的進程用來執行該請求;但如果池中的進程數已經達到規定最大值,那麼該請求就會等待,直到池中有進程結束,才會創建新的進程來它。


import requests
from multiprocessing import Pool, Manager # 進程池Pool Manager().Queue() # 進程池中的隊列
import time
import os # 查看進程的pid
# a = Manager().Queue() # 進程池中的隊列


def work(q):
# 判斷隊列是否有任務
while q.qsize() > 0:
# 獲取任務
url = q.get()
requests.get(url)
print('任務1{}'.format(os.getpid()))


if __name__ == '__main__':
# 進程池中的隊列
q = Manager().Queue()
for i in range(10):
# 增加任務
q.put('//localhost:3000/login')
# 創建進程池 最大進程數為3
p = Pool(3)
for i in range(10):
# 開啟進程執行任務 在進程池中,初始化幾個進程,輪詢執行任務,當一個任務執行完畢後這個進程會去執行另一個任務,直到所有任務完成
if q.qsize() > 0:
        # 每次循環將會用空閑出來的子進程去調用目標
p.apply_async(work, args=(q,)) # 非同步的效率,也就是池中的進程一次性都去執行任務. 進程中有3個進程,一下就處理3個任務,接下來哪個進程處理完任務了,就馬上去接收下一個任務

p.close() # 進程池使用完畢一定要關閉進程池:停止往進程池中添加新的任務
p.join() # 等待po中所有子進程執行完成,必須在close之後 等待執行緒池中的所有任務都執行完了之後再往下執行
# 非同步處理任務時 : 必須要加上close和join. 進程池的所有進程都是守護進程(主進程程式碼執行結束,守護進程就結束).