2016-05-04 7 views
3

Ich habe einen kleinen Code-Schnipsel erstellt (der ursprüngliche Code ist viel größer), die eine Funktion aufruft, die ein Objekt erstellt, sondern in einem Pool von Prozessen:Multi nicht neu erstellen nicht Objekt

import multiprocessing 


class TestClass(object): 
    pass 


def func(): 
    obj = TestClass() 
    cpname = multiprocessing.current_process().name 
    print "{0}, Address: {1}".format(cpname, str(obj)) 


pool = multiprocessing.Pool(2) 
results = [pool.apply_async(func) for _ in range(2)] 

for res in results: 
    res.get() 

pool.close() 
pool.join() 

Wenn ich laufe dieser Code, erhalte ich die folgende Ausgabe:

PoolWorker-1, Address: <__main__.TestClass object at 0x7f05d3fdad50> 
PoolWorker-2, Address: <__main__.TestClass object at 0x7f05d3fdad50> 
  1. Was ich nicht verstehe ist, warum die Objekte die gleiche Adresse haben, auch wenn die in getrennten Prozessen?

  2. Wie kann ich sicherstellen, dass jeder Prozess ein eigenes Objekt erstellt?

Vielen Dank, Ihre Hilfe.

Antwort

2

Die Objekte unterschiedlich sind, verwenden unterschiedliche Prozesse unterschiedliche virtual address space und die gleiche Adresse in verschiedenen Prozessen verweist auf die unterschiedlichen Speicherbereich.

Wenn Sie Ihr Beispiel wenig ändern werden Sie sehen, dass zurückgegebenen Objekte sind unterschiedlich:

import multiprocessing 

class TestClass(object): 
    pass 

def func(): 
    obj = TestClass() 
    cpname = multiprocessing.current_process().name 
    print "{0}, Address: {1}".format(cpname, str(obj)) 
    return obj 

pool = multiprocessing.Pool(2) 
results = [pool.apply_async(func) for _ in range(2)] 

results = [res.get() for res in results] 

pool.close() 
pool.join() 

print results 
3

Wenn Sie fork() für Multiprocessing, dupliziert es Ihren Prozess. Der Speicherzuordner und alle Adressen im übergeordneten Prozess werden in den untergeordneten Prozess kopiert. Folglich wird die nächste Zuweisung sehr wahrscheinlich die gleiche Adresse haben.

können Sie überprüfen, ob sie wie so in der Tat getrennte Objekte sind:

import time 

def func(): 
    obj = TestClass() 
    obj.name = multiprocessing.current_process().name 
    print obj.name, str(obj) 
    time.sleep(1) 
    print obj.name, str(obj) 
+0

Ich habe Ihren Code ausführen. Das Ergebnis verwirrt mich ein wenig, als Adressen immer noch die gleichen sind (oder ist das zu erwarten): 'PoolWorker-1 <__ Haupt __ Testclass-Objekt bei 0x7ffecd3c8d90.> PoolWorker-2 <__ Haupt __ Testclass-Objekt bei 0x7ffecd3c8d90.> PoolWorker -1 <__ main __. TestClass-Objekt bei 0x7ffecd3c8d90> PoolWorker-2 <__ main __. TestClass-Objekt bei 0x7ffecd3c8d90> ' – user1852692

+0

Die Adressen werden aufgrund der virtuellen Adressierung voraussichtlich identisch sein. Wenn Sie ein Programm für Multiprocessing klonen, ändern sich die virtuellen Adressen nicht, aber der zugrunde liegende physische Speicher. – lunixbochs

1

wahrscheinlich scheint, dass Sie ein Linux-ish-System verwenden, in dem neue Verfahren über fork() erstellt werden. In diesem Fall sollten Sie erwarten, eine große Überlappung zwischen Adressen. Das bedeutet nicht, dass Ihre obj Instanzen den gleichen physischen Speicher belegen - nur dass sie dieselben virtuellen (prozesstechnischen) Adressen haben.

Mehr hier:

What happens to address's, values, and pointers after a fork()

Verwandte Themen