這個問題的答案相互矛盾:Are Python multiprocessing Pool thread safe?
我是并發模式的新手,我正在嘗試運行一個專案,該專案接受一個陣列并將該陣列的作業分配給多個行程。陣列很大。
inputs = range(100000)
with Pool(2) as pool:
res = pool.map(some_func, inputs)
我的理解是池會將任務分配給行程。我的問題是:
- 這個地圖操作執行緒安全嗎?兩個行程是否會意外嘗試處理相同的值?
- 我從表面上理解任務將被分成塊并發送到行程。但是,如果不同的輸入比其他輸入花費更多的時間,作業是否總是均勻地分布在我的流程中?我是否會遇到這樣一種情況:一個行程掛起,但在其他行程空閑時有一長串任務要做?
- 我的理解是,由于我只是在讀取輸入,因此不需要使用任何行程間通信模式,例如服務器管理器/共享記憶體。是對的嗎?
- 如果我設定的行程數多于內核數,它是否會像 CPU 在任務之間切換的執行緒一樣運行?
謝謝!
uj5u.com熱心網友回復:
- 使用提供的代碼,不可能有
inputs多個行程處理同一個專案(如果物件的同一個實體在作為引數傳遞的迭代中出現不止一次,則例外)。然而,這種使用多處理的方式有很多開銷,因為inputs專案被一個一個地發送到行程。更好的方法是使用chunksize引數:
inputs = range(100000)
n_proc = 2
chunksize = len(inputs)//n_proc
if len(inputs) % n_proc:
chunksize = 1
with Pool(nproc) as pool:
res = pool.map(some_func, inputs, chunksize=chunksize)
這樣,塊的inputs一次傳遞給每個行程,從而獲得更好的性能。
除非您提出要求,否則作品不會分成大塊。如果沒有
chunksize提供,則每個塊都是可迭代物件中的一項(相當于chunksize=1)。每個塊將被一個一個地“發送”到池中的可用行程。當行程完成前一個塊的作業并變得可用時,這些塊被發送到行程。不需要每個行程都采用相同數量的塊。在您的示例中,如果some_func較大的值需要更長的時間,并且chunksize = len(items)/2獲取前半部分inputs(具有較小值)的塊的程序將首先完成,而另一部分則需要更長的時間。在這種情況下,較小的塊是更好的選擇,因此作業分布均勻。這取決于做什么
some_func。如果不需要some_func(n)to process的結果some_func(m),則不需要在行程之間進行通信。如果您正在使用map并且需要在行程之間進行通信,那么您很可能正在采取一種糟糕的方法來解決您的問題。如果
max_workers > os.cpu_count()CPU 在行程之間切換比在行程數量較少時更頻繁。不要忘記,在一臺(不是很舊的)計算機中運行的行程比你的程式多得多。在 Windows 中,max_workers必須等于或小于 61(請參閱此處的檔案)
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/399904.html
標籤:Python 多线程 并发 线程安全 python-多处理
