您好,登錄后才能下訂單哦!
這篇文章給大家介紹怎么在python中實現multiprocessing多進程變量共享,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
利用Value在不同進程中同步變量
在多進程中,由于進程之間內存相互是隔離的,所以無法在多個進程中用直接讀取的方式共享變量,這時候就可以用multiprocessing庫中的 Value在各自隔離的進程中共享變量。
下面是一個多進程的例子:
假設有一個counter用來記錄程序經過的總循環次數,每調用一次count函數之后counter就會增加20,在主程序中用循環開10個進程分別調用count函數,那么理想狀態下,在十個進程中共享的counter值到程序結束后應該是200。
from multiprocessing import Process, Value import time def count(v): for i in range(20): time.sleep(0.01) v.value += 1 def main(): value = Value('i',0) processes = [Process(target=count, args=(value,)) for i in range(10)] for p in processes: p.start() for p in processes: p.join() print(value.value) if __name__ == '__main__': for i in range(10): main()
運行這個例子,會得到怎樣的結果呢?
188
180
168
186
183
179
186
181
166
186
我在主程序里運行了十次這個程序,而最后的結果是160-180之間,總之,沒有一次到200。這是什么原因呢?
相信很多人都已經明白了問題所在,那就是因為在multiprocessing庫中的Value是細粒度的,Value中有一個ctypes類型的對象,擁有一個value屬性來表征內存中實際的對象。Value可以保證同時只有一個單獨的線程或進程在讀或者寫value值。這么看起來沒有什么問題。
然而在第一個進程加載value值的時候,程序卻不能阻止第二個進程加載舊的值。兩個進程都會把value拷貝到自己的私有內存然后進行處理,并寫回到共享值里。
那么這么會出現什么問題呢?
最后的共享值只接收到了一次值的增加,而非兩次。
利用Lock在不同進程共享變量時加鎖
上面的問題其實可以用一個非常簡單的方法解決,我們只需要調用multiprocessing庫中的Lock (鎖)就可以保證一次只能有一個進程訪問這個共享變量。修改后的代碼如下:
from multiprocessing import Process, Value, Lock from time import sleep def count(x,lock): for i in range(20): sleep(0.01) with lock: x.value += 1 def main(): counter = Value('i',0) lock = Lock() processes = [Process(target=count,args=(counter,lock)) for i in range(10)] for p in processes: p.start() for p in processes: p.join() print(counter.value) if __name__ == '__main__': for i in range(10): main()
這樣一來,輸出的結果就會恒定為200了。
一些補充
1. 調用get_lock() 函數
其實Value這個包里已經包含了鎖的概念,如果調用get_lock() 函數就可以自動給共享變量加鎖。這樣其實是比較推薦的方式,因為這樣就不需要同時調用兩個包。修改如下:
from multiprocessing import Process, Value from time import sleep def count(x): for i in range(20): global counter # 聲明全局變量 sleep(0.01) with counter.get_lock(): # 直接調用get_lock()函數獲取鎖 x.value += 1 def main(): processes = [Process(target=count, args=(counter,)) for i in range(10)] for p in processes: p.start() for p in processes: p.join() print(counter.value) if __name__ == '__main__': counter = Value('i', 0) # 需要把全局變量移到主程序 main()
關于怎么在python中實現multiprocessing多進程變量共享就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。