2018-08-18

進程(Process):
計算機中正在進行的應用程序叫做進程。一個進程包含了該應用程序的所有信息,如加載數(shù)據內存空間、代碼、程序數(shù)據、對象句柄、執(zhí)行單元等等。
計算機中多線程的操作已經實現(xiàn)了多任務的處理機制了,但是多核CPU下的多進程并發(fā)編程的實現(xiàn),能比多線程并發(fā)機制更加有效的利用和發(fā)揮硬件優(yōu)勢。
Python中的multiprocessing模塊,可以實現(xiàn)多進程并發(fā)編程。
import multiprocessing?。DK中常見的屬性和方法
名稱 作用
.Process # 進程類型用于創(chuàng)建、管理一個進程
.Lock/Rloak # 進程互斥鎖/重用鎖,用于進程同步
.Event # 進程事件類型,用于進程同步
.Condition # 進程條件類型,用于進程同步
.Queue # 進程隊列類型,用于多進程數(shù)據共享
.Manager # 進程管理類型,多進程數(shù)據共享
.Listener|Client # 進程監(jiān)聽|客戶端,基于網絡多進程之間的數(shù)據共享
1、多進程的基本操作
1.1 創(chuàng)建一個面向過程的函數(shù)式進程
import multiprocessing, time, os
def hello_world():
# 輸出信息, 展示當前進程編號, 父進程編號
print("hello myname is process", os.getpid(),os.getppid())
if __name__ == "__main__":
proc = multiprocessing.Process(target=hello_process) # 創(chuàng)建一個進程
proc.start() ?。舆M程
print("hello, i ma main:", os.getpid(), os.getppid())
運行程序,查看運行結果,通過進程編號就能看到主進程和創(chuàng)建的進程之間的關系:
hello , i am main : 2456 2772
hello my name is process 13536 2456
從運行結果就能發(fā)現(xiàn),main 方法運行的是主進程,通過multiprocessing 創(chuàng)建的子進程是由主進程產生的!
其中 2772 是 pycharm 工具進程創(chuàng)建的程序主進程
->2456 當前程序進程
->13536 子進程
1.2 面向對象的面向對象編程-_-||
多進程的面向對象,的實現(xiàn)方式,類似多線程的操作模式
自定義進程類型:繼承系統(tǒng)進程標準類型multiprocessing.Process
重寫父類的run()方法,在方法中定義執(zhí)行代碼,run方法不用調用,會自動執(zhí)行!!
在使用時創(chuàng)建自定義進程類型的對象,調用對象的start()方法啟動一個新的進程
import multiprocessing, os
class My_process(multiprocessing.Process):
'''自定義一個進程類型'''
def run(self): # 重寫run方法
print("hello, my name id process", os.getpid(), os.getppid())
if __name__ == "__main__":
print("hello, my name is main", os.,getpid(), os.getppid())
# 創(chuàng)建一個進程
my_proc = Myprocess()
?。右粋€進程
my_proc.start()
執(zhí)行結果,和函數(shù)式編程的結果相同:
hello, my name is main: 7048 2772
hello, my name is process: 3140 7048
- 多進程模式下的數(shù)據操作
?。ǘ嗑€程的操作模式下,全局變量十多個線程共享的。所以多線程并發(fā)模式下對于數(shù)據的修改非常危險?。?br> 多進程模式下,全局變量的參數(shù)是不共享的。在執(zhí)行代碼時,全局變量的值會被進程復制到進程自己的代碼塊里執(zhí)行,全局變量的參數(shù)是不會變的??!
代碼見下方:
import multiprocessing, time
# 定義全局變量
bl = 3
# 定義進程函數(shù)
def change_num():
global bl
while bl > 0:
bl -= 1
print(multiprocessing.Process().name, '進程里的全局變量:', bl)
if __name__ == "__main__":
# 創(chuàng)建兩個進程,并修改數(shù)據
for i in range(2):
p = multiprocessing.Process(target = change_num)
p.start()
time.sleep(2)
print("這是全局變量", bl)
運行結果如下:
Process-1:1 進程里的全局變量: 2
Process-1:2 進程里的全局變量: 1
Process-1:3 進程里的全局變量: 0
Process-2:1 進程里的全局變量: 2
Process-2:2 進程里的全局變量: 1
Process-2:3 進程里的全局變量: 0
這是全局變量 3
可以發(fā)現(xiàn)進程里的全局變量的值雖然發(fā)生了變化,
但是外部全局變量的值沒有改變?。?/p>
- 多進程的簡化:內置進程池
通過進程池Pool,可以快速創(chuàng)建多個進程執(zhí)行指定函數(shù),完成餡餅發(fā)處理操作
Pool的屬性和方法:
名稱 作用
apply(func, args) #args-要傳遞參數(shù), func-要執(zhí)行的函數(shù)名稱,同時阻塞當前進程知道該函數(shù)執(zhí)行完成。
函數(shù)func只會在進程池中的一個進程池運行
---------------------------------------------------
#該方法不會形成阻塞
apply_async(func, args, callback, error_callback)
func ?。╝rgs-要傳遞參數(shù), func-要執(zhí)行的函數(shù)名稱
args 函數(shù)執(zhí)行完成之后可以通過結果對象的 get()方法獲取結果 )
callback #如果結果對象可用時會自動調用 callback 指定的函數(shù)
error_callback #如果結果對象調用失敗時會自動調用 error_callback 指定的函數(shù)
---------------------------------------------------
.close() #Pool 進程池的底層工作機制是向進程池提交任務產生工作進程執(zhí)行
該方法是主動停止給進程池提交任務,并等待所有提交任務執(zhí)行完成退出
.terminate() #立即結束該進程,當進程池對象被回收時自動調用該方法
.join() # 等待工作進程退出,再次之間必須調用 close()或者 teminate
實例如下:
import multiprocessing, time, os
def my_proc():
print(multiprocessing.current_process().name, "一個進程正在工作", os.getppid(), os.getpid())
time.sleep(1)
if __name__ == "__main__":
# 創(chuàng)建一個進程池
pool = multiprocessing.Pool(2)
# 循環(huán)任務
for i in range(20):
pool.apply_async(my_proc)
# 停止提交任務
pool.close()
# 獨占執(zhí)行
pool.join()
結果如下:
SpawnPoolWorker-1 一個進程正在工作 11596 14100
SpawnPoolWorker-2 一個進程正在工作 11596 13680
SpawnPoolWorker-1 一個進程正在工作 11596 14100
SpawnPoolWorker-2 一個進程正在工作 11596 13680
SpawnPoolWorker-2 一個進程正在工作 11596 13680
SpawnPoolWorker-1 一個進程正在工作 11596 14100
SpawnPoolWorker-1 一個進程正在工作 11596 14100
SpawnPoolWorker-2 一個進程正在工作 11596 13680
SpawnPoolWorker-2 一個進程正在工作 11596 13680
SpawnPoolWorker-1 一個進程正在工作 11596 14100
SpawnPoolWorker-2 一個進程正在工作 11596 13680
SpawnPoolWorker-1 一個進程正在工作 11596 14100
SpawnPoolWorker-2 一個進程正在工作 11596 13680
SpawnPoolWorker-1 一個進程正在工作 11596 14100
SpawnPoolWorker-2 一個進程正在工作 11596 13680
SpawnPoolWorker-1 一個進程正在工作 11596 14100
SpawnPoolWorker-2 一個進程正在工作 11596 13680
SpawnPoolWorker-1 一個進程正在工作 11596 14100
SpawnPoolWorker-2 一個進程正在工作 11596 13680
SpawnPoolWorker-1 一個進程正在工作 11596 14100
Process finished with exit code 0
可以發(fā)現(xiàn)進程池里的兩個進程處理了循環(huán)的8個任務
- 多個進程通信,即數(shù)據實現(xiàn)共享(待實際操作)
Python中提供了multiprocessing.Manager類型,該類型內置了大量的用于實現(xiàn)數(shù)據共享的操作
常見的屬性和方法:
名稱 描述
Array 內置進程間共享 數(shù)組 類型
Queue 內置進程間共享 隊列 類型
list() 內置進程間共享 列表 類型
dict() 內置進程間共享 字典 類型
value 內置進程間共享 值 類型