問題
我正在制作一個多處理塊生成器,但我無法通過子行程的 id 獲取物件。我在 Windows 10 上。
代碼
import _ctypes
import classes as pycraft
import multiprocessing
def start_generaion(window):
# We don't have to worry about infinite loops, because
# this is going to be run in another thread, using popen.
try:
world = _ctypes.PyObj_FromPtr(window).model
print(world, flush=True)
while True:
for i in world._queue:
world.all_chunks[i].generate()
except Exception as e:
print(f'Error in world generation process. \n{e}', flush=True)
if __name__ == '__main__':
world = pycraft.world()
world = id(world)
world_gen_process = multiprocessing.Process(target = start_generaion, args = (world,))
world_gen_process.start()
提前致謝!
uj5u.com熱心網友回復:
以下代碼將常規物件的 id 傳遞給另一個行程,它能夠在 Linux 下成功地從 id 中恢復物件:
import _ctypes
import multiprocessing
import sys
def foo(id1, label):
try:
print(label, id1)
v = _ctypes.PyObj_FromPtr(id1)
print(v)
except:
print("Unexpected error:", sys.exc_info()[0])
finally:
print('finally')
if __name__ == '__main__':
d = {'a': 1}
id1 = id(d)
foo(id1, 'Main process id:')
p = multiprocessing.Process(target=foo, args=(id1, 'Subprocess id:'))
p.start()
p.join()
印刷:
Main process id: 140443371291200
{'a': 1}
finally
Subprocess id: 140443371291200
{'a': 1}
finally
但是,當在 Windows 下運行時,輸出的只是:
Main process id: 1687385043136
{'a': 1}
finally
Subprocess id: 1687385043136
子行程突然終止而不執行我沒有解釋的except或塊。finally
問題是,當使用spawn方法創建新行程時,就像 Windows 的情況一樣,該行程不會從主行程繼承任何內容。相反,會創建一個新的地址空間,并在該空間中啟動一個 Python 解釋器,并重新讀取在全域范圍內執行所有內容的源檔案,作為初始化記憶體以準備呼叫作業函式(foo在我的示例中)的方式。但是變數,在新地址空間中不會有相同的地址,除非是最大的巧合。
您沒有說明您在哪個平臺下運行,但我強烈懷疑它使用spawn創建新行程。但即使在 Linux 下,雖然您可以重新創建物件參考,但它實際上只是原始物件的副本(技術上涉及寫入時復制語意,但一旦物件的參考計數增加,就會導致在正在制作的實際副本中)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/415842.html
標籤:
上一篇:使用動態分配的指標初始化成員指標
下一篇:VBA幫助觸發與輸入框相關的事件
