[python] 多程式程式設計
引言
講到程式,不得不先說下linux
的fork()
函式,一個程式呼叫fork()函式後,系統先給新的程式分配資源,例如儲存資料和程式碼的空間。然後把原來的程式的所有值都複製到新的新程式中,只有少數值與原來的程式的值不同。相當於克隆了一個自己。
import os
import time
# 此程式碼只能執行於linux/unix
pid = os.fork() # 建立一個子程式
print("test")
if pid == 0:
print("子程式 {}, 父程式是 {}".format(os.getpid(), os.getppid()))
else:
print("我是父程式: {}".format(pid))
time.sleep(2)
# 執行結果
# test
# 我是父程式: 6428
# test
# 子程式
# 6428, 父程式是 6427
注意到,fork()
後面的程式碼執行了兩次,但行為不一樣。如果fork()
返回0,說明是子程式。而子程式會將父程式的資料原樣拷貝一遍,所以和執行緒不一樣,不能通過全域性變數來通訊。
由於GIL鎖的存在,python
的多執行緒一直被人詬病,在CPU密集型操作中,推薦多程式,在IO密集型操作中,推薦多執行緒。和多執行緒的threading
模組一樣,python
為多程式也提供了multiprocessing
多程式包。
multiprocessing模組
有了多執行緒的使用基礎,多程式的API很好理解。
普通使用
import multiprocessing
import time
def get_html(n):
time.sleep(n)
print("sub_progress success")
return n
if __name__ == "__main__": #注意,在windows下這句話必須加!!!
progress = multiprocessing.Process(target=get_html, args=(2,))
print(progress.pid)
progress.start() # 啟動子程式
print(progress.pid) # 列印子程式的PID
progress.join() # 等待子程式結束
print("main progress end")
# 執行結果
# None
# 5444
# sub_progress success
# main progress end
-
multiprocessing.Process()
傳入執行入口函式和引數。 -
start()
方法啟動子程式。 -
progress.pid
屬性可以獲取子程式的ID號,在未啟動前,未None,啟動後,得到系統分配的ID號。 -
join()
方法等待子程式結束。
程式池
multiprocessing
模組中提供Pool
類來支援程式池程式設計。
import multiprocessing
import time
def get_html(n):
time.sleep(n)
print("sub_progress success")
return n
if __name__ == "__main__": #注意,在windows下這句話必須加!!!
pool = multiprocessing.Pool(multiprocessing.cpu_count())
result = pool.apply_async(get_html, args=(3,))
pool.close() # 在join前必須執行close()
pool.join()
print(result.get()) # 得到子程式的返回值
# 執行結果
# sub_progress success
# 3
- 使用
multiprocessing.Pool()
來建立程式池,可以設定程式池的大小,預設為CPU的核心個數,一般程式也不會超過CPU的核心個數,超過了效率也不會高。 -
apply_async
方法傳入執行入口函式和引數,傳入之後,就進入了子程式等待佇列中,等待執行。返回值是ApplyResult
物件,儲存子程式的結果。 -
join
()方法等待所有子程式的結束,呼叫前必須使用close()
方法。 -
ApplyResult
物件的get()
方法,獲取子程式的返回值。
multiprocessing
模組同樣提供了類似於map
的方法:
import multiprocessing
import time
def get_html(n):
time.sleep(n)
print("{}s sub_progress success".format(n))
return n
if __name__ == "__main__": #注意,在windows下這句話必須加!!!
pool = multiprocessing.Pool(multiprocessing.cpu_count())
# for result in pool.imap_unordered(get_html, [1, 3, 2]):
for result in pool.imap(get_html, [1, 3, 2]):
print("{}s sleep success".format(result))
# 執行結果
# 1s sub_progress success
# 1s sleep success
# 2s sub_progress success
# 3s sub_progress success
# 3s sleep success
# 2s sleep success
-
imap
方法,結果輸出順序與傳入的可迭代物件的順序相同。 -
imap_unordered
方法,結果輸出順序與子程式結束的時間順序相同。
程式池的更好實現
雖然multiprocessing
模組中提供Pool
類,但是使用程式池的時候,使用concurrent.futures
模組中的ProcessPoolExecutor
類更加方便。在介紹執行緒池的時候,介紹了ThreadPoolExecutor
的使用,而ProcessPoolExecutor
的介面實現和ThreadPoolExecutor
完全一樣,只用多建立多執行緒改完建立多程式即可。值得注意的是:在windows下進行多程式程式設計的時候,主程式一定要加if __name__ == "__main__":
。
總結
- 在CPU密集型操作時,使用多程式可以加快速度。
- 多程式API與多執行緒API基本相同,在使用執行緒池的時候,可以使用
multiprocessing.Pool
,也可以使用Future
模組下的ProcessPoolExecutor
,推薦後者。 - 在windows下多程式程式設計要加
if __name__ == "__main__":
。
參考
相關文章
- Python多程式程式設計Python程式設計
- Python的多工程式設計Python程式設計
- python中的多工程式設計Python程式設計
- Python多工程式設計介紹Python程式設計
- python 多執行緒程式設計Python執行緒程式設計
- Python多執行緒程式設計Python執行緒程式設計
- Python多程式程式設計基礎——圖文版Python程式設計
- Python 程式設計Python程式設計
- python程式設計Python程式設計
- Python網路程式設計——程式Python程式設計
- Python程式設計-pycharmPython程式設計PyCharm
- Python socket程式設計Python程式設計
- (整合)Linux下的多程式程式設計Linux程式設計
- Python程式設計:探索有趣的程式碼設計模式Python程式設計設計模式
- Python多程序中並行程式設計與程序池Python並行行程程式設計
- (Python程式設計 | 系統程式設計 | 並行系統工具 | 程式退出)Python程式設計並行
- Python多程式Python
- python程式設計基礎Python程式設計
- Python併發程式設計Python程式設計
- python之超程式設計Python程式設計
- Python 程式設計學習Python程式設計
- python程式設計規範Python程式設計
- Python程式設計入門Python程式設計
- Python並行程式設計Python並行行程程式設計
- 好程式設計師Python培訓分享Python程式設計師面試技巧程式設計師Python面試
- Python並行程式設計(七):多程式的基本使用和與多執行緒的差異Python並行行程程式設計執行緒
- Python程式設計 聖誕樹教程 (附程式碼)程式設計師的浪漫Python程式設計師
- 《Python程式設計練習與解答》之程式設計概論Python程式設計
- python:python的多程式Python
- Python併發程式設計系列之多程式(multiprocessing)Python程式設計
- 程式設計師必備Python技能!不會?究竟有多可怕....程式設計師Python
- 01 Python3程式設計之程式設計語法簡介Python程式設計
- 新年程式設計師福利(多圖)程式設計師
- JavaScript多執行緒程式設計JavaScript執行緒程式設計
- python使用多程式Python
- python程式設計有哪些idePython程式設計IDE
- Python 程式設計實用技巧Python程式設計
- python-併發程式設計Python程式設計