Python多处理 - 将结果写在同一文件中



我具有一个简单的函数,可以在sqlite表中写入某些计算的输出。我想在Python中使用多处理并行使用此功能。我的具体问题是,当每个过程试图将结果写入同一表中时,如何避免冲突?运行代码给我这个错误:sqlite3.erationalerrationerror:数据库已锁定。

import sqlite3
from multiprocessing import Pool
conn = sqlite3.connect('test.db')
c = conn.cursor()
c.execute("CREATE TABLE table_1 (id int,output int)")
def write_to_file(a_tuple):
    index = a_tuple[0]
    input = a_tuple[1]
    output = input + 1
    c.execute('INSERT INTO table_1 (id, output)' 'VALUES (?,?)', (index,output))
if __name__ == "__main__":
    p = Pool()
    results = p.map(write_to_file, [(1,10),(2,11),(3,13),(4,14)])
    p.close()
    p.join()
Traceback (most recent call last):
sqlite3.OperationalError: database is locked

使用Pool是个好主意。

我看到了这个问题的三个可能的解决方案。

首先,不要让泳池工作者试图将数据插入数据库,而是让工作人员将数据返回到父程。

在父进程中,使用imap_unordered代替map。这是一种疑惑,一旦获得值就开始提供值。父母可以将数据插入数据库。

这将序列化访问数据库,防止问题。

如果要插入数据库中的数据相对较小,则该解决方案将是优选的,但是更新经常发生。因此,如果要更新数据库的时间比计算数据相同或更多的时间。


第二,您可以使用Lock。一名工人应该

  • 获取锁,
  • 打开数据库,
  • 插入值,
  • 关闭数据库,
  • 释放锁。

这将避免将数据发送到父进程的开销。但是,相反,您可能会让工人停下来等待将数据写入数据库。

,如果要插入的数据量为,那么这将是一个首选的解决方案,但是计算数据所需的时间比将其插入数据库所需的时间更长。


第三,您可以让每个工人写入自己的数据库,然后将其合并。您可以直接在SQLite甚至Python中进行此操作。尽管有大量数据,但我不确定后者是否有优势。

数据库已锁定以保护您的数据免受损坏。

我相信您不能同时拥有许多流程来访问相同的数据库,至少没有

conn = sqlite3.connect('test.db')
c = conn.cursor()

如果每个过程都必须访问数据库,则应考虑至少关闭cursor对象c(也许严格严格地,connect对象conn(在每个过程中并重新打开该过程。不知何故,其他进程需要等待当前的过程才能释放锁,然后才能获取锁。(有很多方法可以实现等待(。

isolation_level设置为'EXCLUSIVE'为我修复:

conn = sqlite3.connect('test.db', isolation_level='EXCLUSIVE')

相关内容

  • 没有找到相关文章

最新更新