面試時被問了一道題,當時腦子短路,想錯了,題目是這樣的,程序a中定義了乙個變數m = , 通過multiprocessing的process類定義了2個子程序b, c。b執行
print(m)
然後c執行
print(m)
這本是一道基礎送分題,根據python官方doc,process有3種產生方式:
1. spawn
2.fork
3.forkserver
那麼問題來了,怎麼樣才能讓資料在程序之間共享呢,官方給出了2種方案:
在此之前先看一下沒用shared memory的情景
def f(n, a):
print('f', n, a)
print(id(n), id(a))
n = 3.14
for i in range(len(a)):
a[i] = -a[i]
print('f', n, a)
print(id(n), id(a))
if __name__ == '__main__':
num = 0.0
arr = [i for i in range(5)]
print(id(num), id(arr))
p = process(target=f, args=(num, arr))
p.start()
p.join()
print(num, arr)
執行結果如下:
139887945798280 139887913845704
f 0.0 [0, 1, 2, 3, 4]
139887945798280 139887913845704
f 3.14 [0, -1, -2, -3, -4]
139887945798256 139887913845704
0.0 [0, 1, 2, 3, 4]
驚訝的發現,父子程序中的相同變數記憶體位址相同,但是值不同,這是為何?這涉及到作業系統的實體地址和邏輯位址(虛擬位址)的概念,本文不擴充套件開講,參考父子程序中相同的記憶體位址是邏輯記憶體,對應的是不同的物理記憶體。可以看到,子程序中修改變數不會影響到父程序,因為子程序修改的是自己程序中的副本。
shared memory需要使用multiprocessing的value或者array
def f(n, a):
print(id(n), id(a))
n.value = 3.14
for i in range(len(a)):
a[i] = -a[i]
print(id(n), id(a))
if __name__ == '__main__':
num = value('d', 0.0)
arr = array('i', range(5))
print(id(num), id(arr))
p = process(target=f, args=(num, arr))
p.start()
p.join()
print(id(num), id(arr))
print(num.value, arr[:])
執行結果如下:
140488238568504 140488222726912
140488238568504 140488222726912
140488238568504 140488222726912
140488238568504 140488222726912
3.14 [0, -1, -2, -3, -4]
可以看到,子程序修改了父程序中定義的變數,因為它存在於共享記憶體中
from multiprocessing import process, manager
def f(d, l):
d[1] = 'l'
d['2'] = 2
d[0.24] = none
l.reverse()
if __name__ == '__main__':
with manager() as manager:
d = manager.dict()
l = manager.list(range(5))
p = process(target=f, args=(d, l))
p.start()
p.join()
print(d, l)
執行結果如下:
[4, 3, 2, 1, 0]
可以看到,manager管理下的物件,也可以被其他程序共享。
上述2種方法均為官方提供,詳情可參考官網。
Nginx 父子程序通訊
一.參考 nginx核心講解 後加上參考原始碼,小結下nginx中父子程序 子程序間如何通訊。實現原理網上都可以查出來,主要是通過socketpair 函式實現的,下面捋一下內部流程 1.話說要從ngx start worker processes函式講起,由於 不多,貼出來 static void...
父子程序 孤兒程序 殭屍程序小小總結
unix linux中,子程序通過父程序建立。子程序的結束和父程序的執行是非同步狀態,在乙個程序工作終止後他的父程序需要呼叫wait或waitpid系統呼叫取得子程序的終止狀態。乙個父程序退出,而它的乙個或多個子程序還在執行,那麼這些子程序將成為孤兒程序。孤兒程序將位init程序 pid 1 收養,...
父子程序終止順序與僵死程序
在linux 父子程序與fork一文中,我們知道子程序是在父程序呼叫fork之後生成的。那麼關於父子程序終止先後順序又會有什麼影響呢?對於父程序已經終止的所有程序,它們的父程序都改變為init程序。我們稱這些程序由init程序收養。其操作過程大致是 在乙個程序終止時,核心逐個檢查所有活動的程序,以判...