2013-06-29 166 views
17

第一個問題是Value和Manager()之間有什麼區別?Value?python多處理中的共享變量

二,是否有可能不使用值共享整數變量? 以下是我的示例代碼。我想要的是得到一個整數,而不是值的字典。我所做的只是在整個過程結束後進行更改。有沒有更簡單的方法?

from multiprocessing import Process, Manager 

def f(n): 
    n.value += 1 

if __name__ == '__main__': 
    d = {} 
    p = [] 

    for i in range(5): 
     d[i] = Manager().Value('i',0) 
     p.append(Process(target=f, args=(d[i],))) 
     p[i].start() 

    for q in p: 
     q.join() 

    for i in d: 
     d[i] = d[i].value 

    print d 
+0

相關:http://eli.thegreenplace.net/2012/01/04/shared-counter-with-pythons-multiprocessing –

回答

19

當您使用Value你在共享內存中ctypes對象,默認情況下使用RLock同步。當你使用Manager時,你會得到一個控制服務器進程的SynManager對象,該進程允許對象值由其他進程操縱。您可以使用同一個管理器創建多個代理;沒有必要在你的循環來創建一個新的經理:

manager = Manager() 
for i in range(5): 
    new_value = manager.Value('i', 0) 

Manager可以在計算機上共享,而Value僅限於一臺計算機。 Value會更快(運行下面的代碼來看),所以我認爲你應該使用它,除非你需要支持任意對象或通過網絡訪問它們。

import time 
from multiprocessing import Process, Manager, Value 

def foo(data, name=''): 
    print type(data), data.value, name 
    data.value += 1 

if __name__ == "__main__": 
    manager = Manager() 
    x = manager.Value('i', 0) 
    y = Value('i', 0) 

    for i in range(5): 
     Process(target=foo, args=(x, 'x')).start() 
     Process(target=foo, args=(y, 'y')).start() 

    print 'Before waiting: ' 
    print 'x = {0}'.format(x.value) 
    print 'y = {0}'.format(y.value) 

    time.sleep(5.0) 
    print 'After waiting: ' 
    print 'x = {0}'.format(x.value) 
    print 'y = {0}'.format(y.value) 

總結:

  1. 使用Manager創建多個共享對象,包括類型的字典和 名單。使用Manager在網絡上的計算機之間共享數據。
  2. 使用ValueArray時沒有必要通過網絡共享信息 和​​類型足以滿足您的需求 。
  3. ValueManager更快。

警告

順便說一句,跨進程共享數據/線程,應儘量避免使用。上面的代碼可能會按預期運行,但會增加執行foo所需的時間,事情會變得很奇怪。比較以上:

def foo(data, name=''): 
    print type(data), data.value, name 
    for j in range(1000): 
     data.value += 1 

你需要一個Lock正確地完成這項工作。

關於這一切,我並不是特別需要知道,所以也許別人會來,並提供更多的見解。我想我會提出一個答案,因爲這個問題沒有得到關注。希望有所幫助。

+0

我們可以給Array添加任何值嗎?我無法向Array添加任何值。 – user2435611

+2

@ user2435611,['Array'](http://docs.python.org/2/library/multiprocessing.html#multiprocessing.array)會給你一個共享的ctypes數組。您需要事先確定您正在存儲的數據類型,並提供[類型代碼](http://docs.python.org/2/library/array.html#module-array)。例如,'a = Array('c',10)'創建一個長度爲10的單字符串數組。新條目可以像這樣添加到數組中:'a [0] ='b''。您不能將*任何*值添加到數組中,請參閱[類型代碼列表](http://docs.python.org/2/library/array.html#module-array)。 – ChrisP

+0

那麼我們應該事先決定數組的大小,不能擴大它呢?如果是這樣,最好使用manager.list()。感謝您的幫助:) – user2435611