2016-07-15 5 views
1

Ich bin sehr verwirrt über das Verhalten einiger Multiprocessing-Code, der psycopg2 verwendet, um Abfragen parallel zu einem Postgres db.Multiprocessing-Modul und eindeutige psycopg2-Verbindungen

Im Wesentlichen mache ich die gleiche Abfrage (mit unterschiedlichen Parametern) zu verschiedenen Partitionen einer größeren Tabelle. Ich benutze multiprocessing.Pool, um eine separate Abfrage abzuzweigen.

Mein Multiprozessing Aufruf sieht wie folgt aus:

pool = Pool(processes=num_procs) 
results=pool.map(run_sql, params_list) 

Mein run_sql Code wie folgt aussieht:

def run_sql(zip2): 
    conn = get_connection() 
    curs = conn.cursor() 
    print "conn: %s curs:%s pid=%s" % (id(conn), id(curs), os.getpid()) 
    ... 
    curs.execute(qry) 
    records = curs.fetchall() 

def get_connection() 
    ... 
    conn = psycopg2.connect(user=db_user, host=db_host, 
         dbname=db_name, password=db_pwd) 

    return conn 

So ist meine Erwartung, dass jeder Prozess eine separate DB-Verbindung über den Anruf zu get_connection() bekommen würde und dass print id(conn) einen eindeutigen Wert anzeigen würde. Dies scheint jedoch nicht der Fall zu sein, und ich kann es nicht erklären. Sogar print id(curs) ist das gleiche. Nur print os.getpid() zeigt einen Unterschied. Verwendet es irgendwie die gleiche Verbindung für jeden gegabelten Prozess?

conn: 4614554592 curs:4605160432 pid=46802 
conn: 4614554592 curs:4605160432 pid=46808 
conn: 4614554592 curs:4605160432 pid=46810 
conn: 4614554592 curs:4605160432 pid=46784 
conn: 4614554592 curs:4605160432 pid=46811 

Antwort

3

Ich denke, ich habe das herausgefunden. Die Antwort liegt in der Tatsache, dass das Multiprocessing in Python geteilt wird - nichts, also wird der gesamte Speicherplatz kopiert, funktioniert und alles. Daher sind die Speicherräume für jeden Prozess, auch wenn die pid unterschiedlich ist, Kopien voneinander und die Adresse der Verbindung innerhalb des Speicherplatzes ist die gleiche. Aus dem gleichen Grund ist es auch nutzlos, einen globalen Verbindungspool so zu deklarieren, wie es ursprünglich der Fall war. Jeder Prozess endete mit einem eigenen Verbindungspool mit jeweils nur einer aktiven Verbindung.