進程的數據是獨立存在的,進程也能加鎖。python
from multiprocessing import Process, Lock def f(l,i): l.acquire() print('hello world',i) l.release() if __name__ =='__main__': lock = Lock() #得到鎖的實例 for i in range(10): Process(target=f,args=(lock,i)).start() #啓動進程,而且把鎖的實例傳到進程
運行結果數據庫
hello world 0 hello world 2 hello world 1 hello world 3 hello world 6 hello world 7 hello world 8 hello world 4 hello world 5 hello world 9
進程爲何要加鎖?app
由於進程的數據是獨立存在的,並不會共享同一塊數據。可是有些資源是共享的,好比顯示器。若是每一個進程都要輸出內容,那麼顯示的就很亂了,這個鎖就是在某個進程獨自輸出的時候獨佔,不會被其它進程干擾。異步
apply 同步執行 串行async
apply_async 異步執行 並行函數
from multiprocessing import Process, Pool,freeze_support import time import os def Foo(i): time.sleep(2) print('當前進程',os.getpid()) return i + 100 def Bar(arg): print("-->exec done:",arg) if __name__ =='__main__': freeze_support() pool = Pool(processes=5) #容許進程池中同時放入5個進程 for i in range(10): #pool.apply_async(func=Foo,args=(i,),callback=Bar) pool.apply(func=Foo,args=(i,)) print('end') pool.close() pool.join() #進程池中進程執行完畢後在關閉,若是註釋,那麼程序直接關閉。.join()
運行結果ui
當前進程 5816 #sleep 2s 打印 當前進程 8124 #sleep 2s 打印 當前進程 6488 #sleep 2s 打印 當前進程 5356 當前進程 7036 當前進程 5816 當前進程 8124 當前進程 6488 當前進程 5356 當前進程 7036 end
以上是同步執行,程序顯示的效果是串行化執行。spa
並行化blog
from multiprocessing import Process, Pool,freeze_support import time import os def Foo(i): time.sleep(2) print('當前進程',os.getpid()) return i + 100 def Bar(arg): print("-->exec done:",arg) if __name__ =='__main__': freeze_support() pool = Pool(processes=5) #容許進程池中同時放入5個進程 for i in range(10): pool.apply_async(func=Foo,args=(i,),callback=Bar) #pool.apply(func=Foo,args=(i,)) print('end') pool.close() pool.join() #進程池中進程執行完畢後在關閉,若是註釋,那麼程序直接關閉。.join()
運行結果進程
end 當前進程 6060 #一次打印5個 當前進程 6952 -->exec done: 100 -->exec done: 101 當前進程 3388 -->exec done: 102 當前進程 1600 -->exec done: 103 當前進程 7648 -->exec done: 104 當前進程 6060 當前進程 6952 -->exec done: 105 -->exec done: 106 當前進程 3388 -->exec done: 107 當前進程 1600 -->exec done: 108 當前進程 7648 -->exec done: 109
callback() 回調函數,子進程執行完func,以後在調用的函數。 那麼這個函數是子進程調用的仍是主進程調用的?
from multiprocessing import Process, Pool,freeze_support import time import os def Foo(i): time.sleep(2) print('當前進程',os.getpid()) return i + 100 def Bar(arg): print("-->exec done:",arg,os.getpid()) #顯示調用當前函數的進程id if __name__ =='__main__': freeze_support() pool = Pool(processes=5) #容許進程池中同時放入5個進程 print("主進程",os.getpid()) #顯示主進程id for i in range(10): pool.apply_async(func=Foo,args=(i,),callback=Bar) #pool.apply(func=Foo,args=(i,)) print('end') pool.close() pool.join() #進程池中進程執行完畢後在關閉,若是註釋,那麼程序直接關閉。.join()
運行結果
主進程 7052 end 當前進程 7992 當前進程 1848 -->exec done: 101 7052 -->exec done: 100 7052 當前進程 2212 -->exec done: 102 7052 當前進程 980 當前進程 8064 -->exec done: 103 7052 -->exec done: 104 7052 當前進程 7992 -->exec done: 105 7052 當前進程 1848 -->exec done: 106 7052 當前進程 2212 -->exec done: 107 7052 當前進程 8064 當前進程 980 -->exec done: 109 7052 -->exec done: 108 7052
這裏能夠看到是主進程調用的回調,這些寫的優勢是,好比子進程作了數據備份要寫到數據庫,若是每一個子進程都在執行的函數裏面寫,那麼每一個進程都要鏈接一次數據庫,用主進程調用的方式就是能夠省去這麼多的鏈接數據庫的操做。效率更高。