簡體   English   中英

Python多重處理-共享ID的單獨進程中的全局變量?

[英]Python multiprocessing--global variables in separate processes sharing id?

這個問題中我了解到:

當您使用多重處理打開第二個進程時,將創建一個具有自己全局狀態的Python全新實例。 該全局狀態不會共享,因此子進程對全局變量所做的更改對於父進程將是不可見的。

為了驗證此行為,我做了一個測試腳本:

import time
import multiprocessing as mp
from multiprocessing import Pool
x = [0]  # global
def worker(c):
    if c == 1:  # wait for proc 2 to finish; is global x overwritten by now?
        time.sleep(2)
    print('enter: x =', x, 'with id', id(x), 'in proc', mp.current_process())
    x[0] = c
    print('exit: x =', x, 'with id', id(x), 'in proc', mp.current_process())
    return x[0]

pool = Pool(processes=2)
x_vals = pool.map(worker, [1, 2])
print('parent: x =', x, 'with id', id(x), 'in proc', mp.current_process())
print('final output', x_vals)

輸出(在CPython上)類似於

enter: x = [0] with id 140138406834504 in proc <ForkProcess(ForkPoolWorker-2, started daemon)>
exit: x = [2] with id 140138406834504 in proc <ForkProcess(ForkPoolWorker-2, started daemon)>
enter: x = [0] with id 140138406834504 in proc <ForkProcess(ForkPoolWorker-1, started daemon)>
exit: x = [1] with id 140138406834504 in proc <ForkProcess(ForkPoolWorker-1, started daemon)>
parent: x = [0] with id 140138406834504 in proc <_MainProcess(MainProcess, started)>
final output [1, 2]

我應該如何解釋xid在所有進程中共享但x取不同值的事實? 從概念上講, id不是Python對象的內存地址嗎? 我想如果在子進程中克隆內存空間,這是可能的。 那有什么我可以用來獲取Python對象的實際物理內存地址的東西嗎?

共享狀態

當您使用多重處理打開第二個進程時,將創建一個具有自己全局狀態的Python全新實例。 該全局狀態不會共享,因此子進程對全局變量所做的更改對於父進程將是不可見的。

這里的關鍵點似乎是:

這種全球狀態不會共享...”

... 的是子進程的全局狀態。 但這並不意味着父級的全局狀態的一部分不能與子進程共享,只要子進程不嘗試寫入部分。 發生這種情況時,將復制並更改部分獲取,並且父級將看不到部分。

背景:

在Unix上, “ fork”是啟動子進程的默認方式:

父進程使用os.fork()派生Python解釋器。 子進程開始時實際上與父進程相同。 父進程的所有資源均由子進程繼承。 請注意,安全地分叉多線程進程是有問題的。

僅在Unix上可用。 Unix上的默認值。

Fork是使用寫時復制實現的,因此除非您為x分配新對象,否則不會進行復制,並且子進程與其父進程共享相同的列表。


內存地址

我應該如何解釋x的ID在所有進程中共享但x取不同值的事實?

Fork創建一個子進程,其中虛擬地址空間與父進程的虛擬地址空間相同。 虛擬地址將全部映射到相同的物理地址,直到發生寫時復制。

現代操作系統使用虛擬尋址。 基本上,您在程序內部看到的地址值(指針)不是實際的物理內存位置,而是指向索引表(虛擬地址)的指針,而索引表又包含指向實際的物理內存位置的指針。 由於這種間接方式,如果虛擬地址屬於不同進程的索引表,則可以將同一虛擬地址指向不同的物理地址。 鏈接


那有什么我可以用來獲取Python對象的實際物理內存地址的東西嗎?

似乎沒有辦法獲取實際的物理內存地址( link )。 id返回虛擬 (邏輯)內存地址(CPython)。 從虛擬內存到物理內存地址的實際轉換屬於MMU

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM