简体   繁体   English

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

[英]Python multiprocessing. Finish all processes at the same time

My goal is upload some data to database. 我的目标是将一些数据上传到数据库。 I'm using psycopg2 and it has a rule: all processes must have own database connection. 我正在使用psycopg2,它有一条规则:所有进程都必须具有自己的数据库连接。 In my case it means that I must commit in worker. 就我而言,这意味着我必须从事工人工作。 The problem is that I can commit only all processes finish sql insert command. 问题是我只能提交所有完成sql insert命令的进程。 What I need: 我需要的:

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()

How can I make all process wait untill finish sql commands? 如何使所有进程等到完成sql命令? What is correct way to do this? 正确的方法是什么? This sql insert only for example, in real task i need to insert millions of records. 例如,此sql插入仅在实际任务中需要插入数百万条记录。

You can use a pair of multiprocessing.Event objects to allow both workers to tell the other that they're done, as well as to force them to wait for the other to signal back: 您可以使用一对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()

Just be careful about the possibility of a deadlock if one of the workers fails for some reason. 如果其中一个工人由于某种原因而失败,请当心死锁的可能性。 You may want to set the optional timeout keyword argument of Event.wait to some fairly high value, and rollback if it expires. 您可能希望将Event.wait的可选timeout关键字参数Event.wait为一个相当高的值,如果过期则回滚。 That or use a try / except in each worker that guarantees my_e gets set() , but also share a variable between the two workers that can be used to tell the other worker if a failure occurred. 这或使用try / except在保证每个工人my_eset()但也分享可以用来告诉其他工人如果发生故障两名工人之间的变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM