2015-08-15 75 views
2

我希望能夠使用多處理庫中的Values模塊來跟蹤數據。據我所知,當談到Python中的多處理時,每個進程都有自己的副本,所以我不能編輯全局變量。我想能夠使用值來解決這個問題。有誰知道我可以如何將值數據傳遞到池功能?如何使用Python中的多處理池中的值

from multiprocessing import Pool, Value 
import itertools 

arr = [2,6,8,7,4,2,5,6,2,4,7,8,5,2,7,4,2,5,6,2,4,7,8,5,2,9,3,2,0,1,5,7,2,8,9,3,2,] 

def hello(g, data): 
    data.value += 1 

if __name__ == '__main__': 
    data = Value('i', 0) 
    func = partial(hello, data) 
    p = Pool(processes=1) 
    p.map(hello,itertools.izip(arr,itertools.repeat(data))) 

    print data.value 

下面是運行時錯誤我越來越:

RuntimeError: Synchronized objects should only be shared between processes through inheritance 

有誰知道我做錯了嗎?

+0

我想你需要將你的'data'變量傳遞給所有的進程。 –

+0

@TomDalton我剛剛使用itertools更新了代碼,將數據變量傳遞給hello函數,現在我得到一個錯誤,我不知道它爲什麼發生。 – user2313602

+0

爲什麼不是從'hello()'返回數據呢?這就是「地圖」的全部內容。 –

回答

3

我不知道爲什麼,但似乎有一些問題使用Pool,如果您手動創建子進程,您不會得到這個問題。例如。以下作品:

from multiprocessing import Process, Value 

arr = [1,2,3,4,5,6,7,8,9] 


def hello(data, g): 
    with data.get_lock(): 
     data.value += 1 
    print id(data), g, data.value 

if __name__ == '__main__': 
    data = Value('i') 
    print id(data) 

    processes = [] 
    for n in arr: 
     p = Process(target=hello, args=(data, n)) 
     processes.append(p) 
     p.start() 

    for p in processes: 
     p.join() 

    print "sub process tasks completed" 
    print data.value 

但是,如果你這樣做基本上是相同的使用Pool,那麼你會得到一個錯誤「RuntimeError:同步的對象只能進程之間通過繼承共享」的想法。在使用池之前,我已經看到了這個錯誤,並且從來沒有完全瞭解它的底部。

使用Value的替代,這似乎與Pool工作是使用經理給你一個「共享」列表:

from multiprocessing import Pool, Manager 
from functools import partial 


arr = [1,2,3,4,5,6,7,8,9] 


def hello(data, g): 
    data[0] += 1 


if __name__ == '__main__': 
    m = Manager() 
    data = m.list([0]) 
    hello_data = partial(hello, data) 
    p = Pool(processes=5) 
    p.map(hello_data, arr) 

    print data[0] 
+0

完美!這正是我所期待的!看起來我不得不最終使用管理器!謝謝湯姆! – user2313602

+0

Ref分享價值,這個答案(http://stackoverflow.com/a/9931389/2372812)似乎與池初始化者做一些解決方法,使其工作,但它似乎是一個相當差的解決方案。請注意,與'真正'的共享內存相比,使用管理器會導致潛在的IPC緩慢。 –

1

這裏有一點需要使用ValuesPool.map()

map的核心思想是將函數應用於列表或其他迭代器中的每個項目,並將返回值收集到列表中。

Pool.map背後的想法基本上是相同的,但隨後分散在多個進程。在每個工作進程中,被映射的函數都會被迭代器中的項調用。 返回值從工作進程中調用的函數被傳回父進程並收集到最終返回的列表中。