摘要:很簡單,這個模塊實(shí)現(xiàn)了開辟一塊共享內(nèi)存空間,就好比中的方法一樣,有興趣的同學(xué)可以去查閱。查了下資料,返回的對象控制了一個進(jìn)程,可用于多進(jìn)程之間的安全通信,其支持的類型有和等。
有關(guān)于 multiprocessing 中共享變量的問題
現(xiàn)在的cpu都很強(qiáng)大,比方我用的至強(qiáng)2620有24核可以同時工作,并行執(zhí)行進(jìn)程程序。這在計算密集型的程序是很需要的,如沙漠中的綠洲,令人重獲新生。那么,問題接踵而來,python中多進(jìn)程能否共享一個變量,因?yàn)槲倚枰戮仃嚒?/p>
我的辦法是用list存儲三元組信息,信息包括矩陣位置以及value。那么首先我們設(shè)定一個全局變量叫result_list就可以了?
答案是NO.
進(jìn)程間共享變量就需要獨(dú)立開辟一塊內(nèi)存空間或是文件共享,在python里很方面,直接用一個模塊可以解決這個問題,那就是 multiprocessing 里的 Manager。當(dāng)然,這是針對我們需要的是list而言,如果我們只是共享一個簡單的變量如一個整數(shù),可以直接用 multiprocessing 里的 value。
下面的實(shí)例是怎么去共享變量。
from multiprocessing import Process, Manager, Lock import os lock = Lock() manager = Manager() sum = manager.list() def testFunc(cc, lock): with lock: sum.append(1) if __name__ == "__main__": threads = [] for ll in range(1000): t = Process(target=testFunc, args=(1, lock)) t.daemon = True threads.append(t) sum = manager.list() for i in range(len(threads)): threads[i].start() for j in range(len(threads)): threads[j].join() print "------------------------" print "process id:", os.getpid() print sum
很簡單,manager這個模塊實(shí)現(xiàn)了開辟一塊共享內(nèi)存空間,就好比c中的 shmget 方法一樣,有興趣的同學(xué)可以去查閱。 傳送門
這樣簡單的處理并不能滿足我。
首先,我需要一個線程池,當(dāng)然,實(shí)現(xiàn)線程池也是非常簡單的。但是就會遇到一個問題。
lock = multiprocessing.Lock() pool = multiprocessing.Pool(processes=3) for i in range(0,3): pool.apply_async(child_worker, ((my_parameter, lock),)) pool.close() pool.join()
以上代碼執(zhí)行時會出錯。
RuntimeError: Lock objects should only be shared between processes through inheritance
查了下資料,multiprocessing.Manager()返回的manager對象控制了一個server進(jìn)程,可用于多進(jìn)程之間的安全通信,其支持的類型有l(wèi)ist,dict,Namespace,Lock,RLock,Semaphore,BoundedSemaphore,Condition,Event,Queue,Value和Array等。
所以代碼修改成這樣后就可以正常運(yùn)行了:
lock = multiprocessing.Manager().Lock() pool = multiprocessing.Pool(processes=3) for i in range(0,3): pool.apply_async(child_worker, ((my_parameter, lock),)) pool.close() pool.join()
所以,lock的問題解決了,真是厲害我們現(xiàn)在可以充分地(往死里)用我們的電腦了。
But,還不夠,我想要多次執(zhí)行這個并行化計算sum的函數(shù)。也就是說我需要每次去清空result_list的內(nèi)容,這個可是一個很關(guān)鍵的細(xì)節(jié),因?yàn)檫@個需要明白一個細(xì)節(jié),你不能用sum = [] 這樣的方式去重置,我個人認(rèn)為是局部變量的原因,我后來找到了del sum[:]的方法,解決了我的大問題,so,final version 如下。
from multiprocessing import Process, Manager,Pool import os lock = Manager().Lock() manager = Manager() sum = manager.list() def testFunc(cc, lock): with lock: sum.append(1) # 配合 multiprocessing pool 對多參數(shù)的要求添加的函數(shù) def multi_test(args): testFunc(*args) def testing(): threads = [] _pool = Pool(24) del sum[:] lst_vars = [] for shot in range(1000): lst_vars.append((1,lock)) _pool.map(multi_test, lst_vars) _pool.close() _pool.join() print "------------------------" print "process id:", os.getpid() print sum if __name__ == "__main__": testing() testing()
這些實(shí)例是我方便寫博客想的,其實(shí)我是在寫一個大工程遇到了這些個問題,忙的我焦頭爛額,但是總結(jié)出了人生經(jīng)驗(yàn),希望幫到你,讓你多活幾年~~
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/44435.html
摘要:首發(fā)于我的博客線程池進(jìn)程池網(wǎng)絡(luò)編程之同步異步阻塞非阻塞后端掘金本文為作者原創(chuàng),轉(zhuǎn)載請先與作者聯(lián)系。在了解的數(shù)據(jù)結(jié)構(gòu)時,容器可迭代對象迭代器使用進(jìn)行并發(fā)編程篇二掘金我們今天繼續(xù)深入學(xué)習(xí)。 Python 算法實(shí)戰(zhàn)系列之棧 - 后端 - 掘金原文出處: 安生??? 棧(stack)又稱之為堆棧是一個特殊的有序表,其插入和刪除操作都在棧頂進(jìn)行操作,并且按照先進(jìn)后出,后進(jìn)先出的規(guī)則進(jìn)行運(yùn)作。 如...
摘要:正文總所周知,和根本就是兩個東西,每次因?yàn)檫@個兼容性的問題都會把自己搞瘋。提供了模塊,把下一個新版本的特性導(dǎo)入到當(dāng)前版本,于是我們就可以在當(dāng)前版本中測試一些新版本的特性。傳送門不多,才個。 寫在前面 我是在學(xué)習(xí)cs231n的assignment3的課程,發(fā)現(xiàn)里面的代碼大量頻繁出現(xiàn)了這個庫,那我就很奇怪了,為什么有個future這個奇怪名字的庫會出現(xiàn)呢?到底這個庫又有什么用?下面就讓我為...
閱讀 1796·2021-09-30 09:47
閱讀 3793·2021-09-22 15:05
閱讀 2983·2021-08-30 09:44
閱讀 3719·2019-08-30 15:55
閱讀 1489·2019-08-30 13:08
閱讀 1415·2019-08-29 16:40
閱讀 676·2019-08-29 12:45
閱讀 1474·2019-08-29 11:25