Python多处理。同时完成所有进程

时间:2014-07-17 09:37:32

标签: python locking multiprocessing semaphore psycopg2

我的目标是将一些数据上传到数据库。我使用的是psycopg2,它有一条规则:所有进程都必须拥有自己的数据库连接。在我的情况下,这意味着我必须在工人中承诺。问题是我只能提交所有进程完成sql insert命令。我需要的是:

from multiprocessing import Process

def worker1(s):    
    conn = psycopg2.connect("dbname=mydb user=postgres")
    cursor = conn.cursor()

    pg_cursor.execute(
            """ insert into "MyTable1"("Column1")
                values(%s)""", [1])

    #wait all processes
    conn.commit()       

def worker2(s):    
    conn = psycopg2.connect("dbname=mydb user=postgres")
    cursor = conn.cursor()

    pg_cursor.execute(
            """ insert into "MyTable2"("Column1")
                values(%s)""", [1])

    #wait all processes
    conn.commit()

if __name__ == '__main__':
    p1 = Process(target=worker1)
    p2 = Process(target=worker2)
    p1.start()
    p2.start()

如何让所有进程等待直到完成sql命令?这样做的正确方法是什么? 这个sql插件只是例如,在实际任务中我需要插入数百万条记录。

1 个答案:

答案 0 :(得分:0)

您可以使用一对multiprocessing.Event对象,让两个工作人员告诉对方他们已经完成,并强迫他们等待对方发出信号:

from multiprocessing import Process, Event

def worker1(s, my_e, other_e):    
    conn = psycopg2.connect("dbname=mydb user=postgres")
    cursor = conn.cursor()

    pg_cursor.execute(
            """ insert into "MyTable1"("Column1")
                values(%s)""", [1])

    #wait all processes
    my_e.set()
    other_e.wait()
    conn.commit()       

def worker2(s, my_e, other_e):    
    conn = psycopg2.connect("dbname=mydb user=postgres")
    cursor = conn.cursor()

    pg_cursor.execute(
            """ insert into "MyTable2"("Column1")
                values(%s)""", [1])

    #wait all processes
    my_e.set()
    other_e.wait()
    conn.commit()

if __name__ == '__main__':
    e1 = Event()
    e2 = Event()
    p1 = Process(target=worker1, args=(e1, e2))
    p2 = Process(target=worker2, args=(e2, e1))
    p1.start()
    p2.start()
    p1.join()
    p2.join()

如果其中一名工人由于某种原因失败,请小心死锁的可能性。您可能希望将timeout的可选Event.wait关键字参数设置为相当高的值,如果过期则将其回滚。那个或者在每个保证try获得except的工作者中使用my_e / set(),但也可以在两个工作者之间共享一个可以用来告诉其他工人的变量如果发生了故障。