Python 3.8脚本在获取数据库连接(psycopg2和多处理)时冻结-Windows 7

问题描述 投票:1回答:1

我有一个脚本,该脚本开始四个过程以在数据库上进行插入。它们使用不同的参数共享相同的目标代码。

经过一些调试后,我注意到程序卡住的那一刻是在步骤2:该过程要求数据库连接的步骤。该问题不会立即发生。该程序在冻结之前完成了一些插入。我试图将步骤2、3和4锁定在一起,但是并不能解决问题。我不知道如何解决这个问题。

records是一组对象,这些对象具有将用于将INSERT插入数据库的数据。计数器是用于验证进度的共享值。total用于计算进度百分比。锁是对变量和数据库的独占访问。dataBaseAdapter是一个python模块,该模块导入psycopg2以与数据库建立连接该数据库是PostgreSQL我不知道它是否有任何区别,但是我正在Visual Studio Code上运行它

进程的创建:

len_records = len(records)
counter = Value('i', 0)
lock = Lock()
total = Value('i', len_records)

for index in range(0,len_records,4):
    p1 = encapsulatedProcess(index,jogos,len_records,counter,lock)
    p2 = encapsulatedProcess(index+1,jogos,len_records,counter,lock)
    p3 = encapsulatedProcess(index+2,jogos,len_records,counter,lock)
    p4 = encapsulatedProcess(index+3,jogos,len_records,counter,lock)
    holdProcess(index+1,p1)
    holdProcess(index+2,p2)
    holdProcess(index+3,p3)
    holdProcess(index+4,p4)

ensapsulatedProcess:

def encapsulatedProcess(ind,records,len_records,counter,lock):
    if(ind > len_records): return None
    record = records[ind]
    process = Process(target=my_function, args=(ind,record,counter,lock,), daemon=True)
    process.start()
    return process

holdProcess:

def holdProcess(number,process):
    if(process == None): return
    if(process.is_alive()):
        process.join()
    process.close()
    print(number)

my_function:

def dramaAnalizerLocal(idt,record,counter,lock):
    lock.acquire()
    print(idt," 1 - load model")
    auxiliar = Model(record) #connects with database and closes
    lock.release()

    lock.acquire()
    print(idt," 2 - getting connection")
    conn = dataBaseAdapter.getConnection() 
    lock.release()

    lock.acquire()
    print(idt, " 3 - saving data")
    record.store(InsertIntoType1(model=auxiliar, ignored=1), conn)
    record.store(IntertIntoType2(model=auxiliar, ignored=1),conn)
    record.store(InsertIntoType3(model=auxiliar, ignored=1),conn)
    lock.release()

    lock.acquire()
    print(idt," 4 - closing connection")
    dataBaseAdapter.closeConnection(conn)
    lock.release()

    lock.acquire()
    print(idt," 5 - increment counter") 
    counter.value += 1
    lock.release()

    lock.acquire()
    print(idt," 6 - return")
    lock.release()
python python-3.x multiprocessing database-connection psycopg2
1个回答
0
投票

在Internet上搜索后,问题似乎在于该程序打开和关闭连接的速度过快。因此,建议在所有操作之后立即关闭。我能够通过单个过程传递连接,但是,我不知道如何,该过程继续要求连接。因此,要解决该问题,我做了我害怕做的事情,因为我担心这样做会很困难:安装pgbouncer。事实证明这很容易。我只需要更改程序使用的端口,为pgbouncer提供数据库别名,然后重新启动pgbouncer。

TLDR:安装了pgbouncer并配置了程序和pgbouncer

© www.soinside.com 2019 - 2024. All rights reserved.