我有一个脚本,该脚本开始四个过程以在数据库上进行插入。它们使用不同的参数共享相同的目标代码。
经过一些调试后,我注意到程序卡住的那一刻是在步骤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()
在Internet上搜索后,问题似乎在于该程序打开和关闭连接的速度过快。因此,建议在所有操作之后立即关闭。我能够通过单个过程传递连接,但是,我不知道如何,该过程继续要求连接。因此,要解决该问题,我做了我害怕做的事情,因为我担心这样做会很困难:安装pgbouncer。事实证明这很容易。我只需要更改程序使用的端口,为pgbouncer提供数据库别名,然后重新启动pgbouncer。
TLDR:安装了pgbouncer并配置了程序和pgbouncer