看multiprocessing部分的Python文檔,一點思考:
https://www.rddoc.com/doc/Python/3.6.0/zh/library/multiprocessing/#module-multiprocessing
離職啦,感覺一直拖拖拖,現(xiàn)在反而清醒輕松了不少,開始瘋狂產(chǎn)出吧~
from multiprocessing import Process, Lock
def f(l, i):
l.acquire()
try:
print('hello world', i)
finally:
l.release()
if __name__ == '__main__':
lock = Lock()
for num in range(10):
Process(target=f, args=(lock, num)).start()
這里給進程設置了一個進程鎖lock。lock在不同進程使用同一共享內存時,能夠確保線程之間互不影響,使用lock的方法是, 在每個線程/進程使用共享內存資源或修改共享內存之前,執(zhí)行l(wèi)ock.acquire()將共享內存上鎖, 確保當前進程執(zhí)行時,內存不會被其他進程訪問,執(zhí)行運算完畢后,使用lock.release()將鎖打開, 保證其他的線程可以使用該共享內存。
看似這樣做,進程就會輸出0-9了,但實際上并不會。
# output result
hello world 0
hello world 1
hello world 5
hello world 2
hello world 4
hello world 7
hello world 3
hello world 6
hello world 8
hello world 9
可見,第一個進程必然是0,這毫無疑問,但后面卻散亂排布。這與使用鎖的初衷相違背,這是為什么呢?
思考后發(fā)現(xiàn),在第一個進程執(zhí)行的過程中,即i=0時,它擁有當前的lock,因此它必然是先執(zhí)行的。但是由于進程是非阻塞的,因此在執(zhí)行Process的過程中,還是可以繼續(xù)迭代的,即num=1,2,...,9這個過程中他們都有可能進入Process這一步,等待num=0時執(zhí)行函數(shù)結束,獲得當前的Process,因此后面的順序是不可控的。
如果想要按順序排布,可以將進程設置為阻塞的。即當前進程執(zhí)行完之前,后面的進程會先掛起。這可以通過join()函數(shù)來實現(xiàn)。
# blocking
from multiprocessing import Process, Lock
def f(l, i):
l.acquire()
try:
print('hello world', i)
finally:
l.release()
if __name__ == '__main__':
lock = Lock()
for num in range(10):
p = Process(target=f, args=(lock, num))
p.start()
p.join()
輸出結果為:
# output result
hello world 0
hello world 1
hello world 2
hello world 3
hello world 4
hello world 5
hello world 6
hello world 7
hello world 8
hello world 9