python 進程間共享數據 (一)


def worker(num, mystr, arr):
    num.value *= 2
    mystr.value = "ok"
    for i in range(len(arr)):
        arr[i] = arr[i] * (-1) + 1.5

def dump_vars(num, mystr, arr):
    print 'num: ', num.value
    print 'str: ', mystr[:]
    print 'arr: ', arr[:]

if __name__=='__main__':
    num = Value('i', 5)
    mystr = Array('c', 'just for test')
    arr = Array('d', [1.0, 1.5, -2.0])
    dir(str)
    print 'init value'
    dump_vars(num, mystr, arr)

    ps = [Process(target=worker, args=(num, mystr, arr)) for x in range(3)]
    for p in ps:
        p.start()
    for p in ps:
        p.join()

    print
    print 'after all workers finished'
    dump_vars(num, mystr, arr)

上述代碼打印結果: 

 

注意看紅色框住的內容,多次測試我發現,在共享字符串的時候,在主進程中的初始化決定了這個字符串的長度,
創建后字符串的長度固定不變,相當於把這個字符串所在的地址復制給一個指針,並且在字符串的首地址記錄了自身的長度,
在以后讀取這個值的時候就會去讀取那一段固定長度的內容,而不管現在的新內容長度是多少,舉個例子:
比如我們在主進程初始化一段字符串 "abcde",一旦初始化,長度就固定了,現在長度是5,然后我們在其他進程賦值,我們嘗試賦值為
"abcdefg",此時執行會報錯,因為長度超標了,我們在賦值為 "yes",最后輸出結果為 "yes&efg"(此處的&是代表一個不可顯示的字符,不同的環境下顯示不同,有可能顯示空格,有可能顯示null)。也就是說長短都不行,必須和初始化字符串等長。
於是得出這樣一個結論,如果你要共享一個字符串,那么在子進程中賦值時必須賦值長度相當的字符串。建議在子進程中可以先檢查字符串長度,然后在根據需要拼接指定長度的字符串

上面的分析建立在下面的基礎上,請先看下面的基本用法:

多進程間共享數據,可以使用 multiprocessing.Value 和 multiprocessing.Array

Value(typecode_or_type, *args[, lock])
Value函數返回一個shared memory包裝類,其中包含一個ctypes對象
typecode_or_type typecode列表如下
------------------------------------------------------------------
Type code C Type Python Type
'c' char character
'b' signed char int
'B' unsigned char int
'u' Py_UNICODE Unicode character
'h' signed short int
'H' unsigned short int
'i' signed int int
'I' unsigned int long
'l' signed long int
'L' unsigned long long
'f' float float
'd' double float
---------------------------------------------------------
Array(typecode_or_type, size_or_initializer, *, lock=True)
lock 默認值是True:創建一個新的lock來控制對value的訪問。該參數也可以是 multiprocessing.Lock 或 multiprocessing.RLock 對像,用來控制對value的訪問


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM