標籤:abc 返回 預設值 bsp red 例子 定義 函數返回 from
在代碼最佳化的過程中,碰到了這樣一個問題:一個進程中我定義了幾個全域變數,然後我又Process了幾個子進程,子進程中是否可以各自對全域變數進行修改?最後全域變數會取哪個值呢?
經過一番嘗試以後得到結果:
子進程繼承父進程的全域變數,而且是以複製的形式完成,所以子進程修改後的全域變數只對自己和自己的子進程有影響。
父子進程不共用這些全域變數,也就是說:父進程中對全域變數的修改不影響子進程中的全域變數,同理,子進程也不影響父進程的。
為了實現父子進程的通訊,在網上經過了一番翻找以後,找到了 Value和Array 方法
Value函數返回一個shared memory封裝類,其中包含一個ctypes對象
一般 整數用 i, 字元用 c,浮點數用 d 就可以了
Array函數返回一個shared memory封裝類,其中包含一個數組,字串需要用 Array 來傳遞
- @args shared memory 中包含的值
- @lock 預設值是True:建立一個新的lock來控制對value的訪問。該參數也可以是 multiprocessing.Lock 或 multiprocessing.RLock 對像,用來控制對value的訪問
================================================================================================================================
案例一:
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)
#結果:init valuenum: 5str: just for testarr: [1.0, 1.5, -2.0]after all workers finishednum: 40str: ok
多次測試我發現,在共用字串的時候,在主進程中的初始化決定了這個字串的長度,
建立後字串的長度固定不變,相當於把這個字串所在的地址複製給一個指標,並且在字串的首地址記錄了自身的長度,
在以後讀取這個值的時候就會去讀取那一段固定長度的內容,而不管現在的新內容長度是多少,舉個例子:
比如我們在主進程初始化一段字串 "abcde",一旦初始化,長度就固定了,現在長度是5,然後我們在其他進程賦值,我們嘗試賦值為
"abcdefg",此時執行會報錯,因為長度超標了,我們在賦值為 "yes",最後輸出結果為 "yes&efg"(此處的&是代表一個不可顯示的字元,不同的環境下顯示不同,有可能顯示空格,有可能顯示null)。也就是說長短都不行,必須和初始化字串等長。
於是得出這樣一個結論,如果你要共用一個字串,那麼在子進程中賦值時必須賦值長度相當的字串。建議在子進程中可以先檢查字串長度,然後在根據需要拼接指定長度的字串
案例二:
from multiprocessing import Process, Value, Arraydef f(n, a): n.value = n.value + 1 for i in range(len(a)): a[i] = a[i] * 10if __name__ == ‘__main__‘: num = Value(‘i‘, 1) arr = Array(‘i‘, range(10)) p = Process(target=f, args=(num, arr)) p.start() p.join() print(num.value) print(arr[:]) p2 = Process(target=f, args=(num, arr)) p2.start() p2.join() print(num.value) print(arr[:])# the output is :# 2# [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]# 3# [0, 100, 200, 300, 400, 500, 600, 700, 800, 900]
Python 多進程 Value、Array應用記錄