進程
由於GIL
的存在,Python中的多線程其實並不是真正的多線程,如果想要充分地使用多核CPU
的資源,在Python中大部分情況需要使用多進程。Python提供了非常好用的多進程模塊multiprocessing
,只需要定義一個函數,Python會完成其他所有事情。藉助這個模塊,可以輕鬆完成從單進程到並發執行的轉換。multiprocessing
支持子進程、通信和共享數據、執行不同形式的同步,提供了Process
、Lock
、Queue
、Pipe
等組件。
multiprocessing
包是Python中的多進程模塊。與threading.Thread
類似,它可以利用multiprocessing.Process
對象來創建一個進程。該進程可以運行在Python程序內部編寫的函數。該Process對象與Thread對象的用法相同,也有start()
,run(),
join()
的方法。此外multiprocessing
模塊中也有Lock
/Event
/Semaphore
/Condition
類 (這些對象可以像多線程那樣,通過參數傳遞給各個進程),用以同步進程,其用法與threading
模塊中的同名類一致。所以,multiprocessing
的很大一部份與threading
使用同一套API,只不過換到了多進程的情境。
當然多進程的定義方式也和多線程類似,即兩種方式:
目標函數實例化定義新的進程:
# 導入多進程模塊
from multiprocessing import Process
# os.getpid() 獲取當前進程的id
import os
def run_proc(name):
print({} child process is {}.format(name, os.getpid()))
if __name__ == __main__:
print("Parent process is {}".format(os.getpid()))
p = Process(target=run_proc, args=(test, ))
print(child process will start...)
p.start()
p.join()
print(child process end.)
運行截圖如下:
運行截圖
繼承類來定義新的進程
from multiprocessing import Process
import os
class RunProc(Process):
def __init__(self, name):
Process.__init__(self)
self.name = name
def run(self):
print({} child process is {}.format(self.name, os.getpid()))
if __name__ == "__main__":
print("Parent process is {}".format(os.getpid()))
p = RunProc(test)
print(child process will start...)
p.start()
p.join()
print(child process end.)
運行結果如下:
運行截圖
我們可以看見,多進程的使用方式和多線程幾乎一樣,比如以下:
Process([group [, target [, name [, args [, kwargs]]]]])
group: 線程組,目前還沒有實現,庫引用中提示必須是None;
target: 要執行的方法;
name: 進程名;
args/kwargs: 要傳入方法的參數。
實例方法:
is_alive():返回進程是否在運行。
join([timeout]):阻塞當前上下文環境的進程程,直到調用此方法的進程終止或到達指定的timeout(可選參數)。
start():進程準備就緒,等待CPU調度
run():strat()調用run方法,如果實例進程時未制定傳入target
,start
執行默認的· run()
方法。
terminate():不管任務是否完成,立即停止工作進程
屬性:
daemon:和線程的setDeamon
功能一樣
exitcode(進程在運行時為None、如果為–N,表示被信號N結束)
name:進程名字。
pid:進程號。
進程的獨立性:
和線程不一樣的是,進程之間相互獨立,我們可以從全局變數的修改窺見一些:
from multiprocessing import Process
# 測試數據
ex_list = Hello World
# 修改數據進程
def revise_data():
global ex_list
# 修改全局變數
ex_list = ex_list + with write revise_data process.
print(wirte result:, ex_list)
# 查看數據進程
def view_data():
print(ex_list)
if __name__ == "__main__":
process_revise = Process(target=revise_data)
process_view = Process(target=view_data)
process_revise.start()
# 主進程等待寫入進程執行完成以後代碼 再繼續往下執行
process_revise.join()
process_view.start()
process_view.join()
print("process end.")
運行截圖如下:
運行結果
我們定義了兩個進程,分別用來修改全局變數和查看修改後的數據,我們看見雖然修改的進程已經成功修改了變數,但是在查看進程中全局變數仍然是原來的值,即進程之間是不共享全局變數的,即創建子進程其實是對主進程進行拷貝,進程之間相互獨立,訪問的全局變數不是同一個,所以進程之間不共享全局變數。
推薦閱讀:
Please enable JavaScript to view the comments powered by Disqus.