SQLite 读取多处理,不启动 imap
SQLite reads with multiprocessing, not starting the imap
我已经尝试了所有我能想到的方法,但我无法弄清楚为什么以下多处理代码不会启动循环:
import sqlite3, itertools
# Dummy table
conn = sqlite3.connect(":memory:")
conn.execute('CREATE TABLE numbers (num integer)')
conn.executemany("INSERT INTO numbers VALUES (?)",
((x,) for x in range(5)))
conn.commit()
cmd_search = "SELECT * FROM numbers"
cursor = conn.execute(cmd_search)
def nothing(x): return x
import multiprocessing
P = multiprocessing.Pool()
#ITR = P.imap(nothing,cursor) # parallel version
ITR = itertools.imap(nothing, cursor) # serial version
for x in ITR: print x
当我 运行 使用 "serial" 版本(使用 itertools.imap
)时,我得到了 (0,) (1,) (2,) (3,) (4,)
的预期输出。使用 multiprocessing.imap
版本,我什么也没得到,循环退出。我显然与 sqlite 游标有关,切换到 cursor=range(5)
有效。
为什么多处理在这里不起作用?
默认情况下 sqlite3
不允许您在实际创建它的线程之外访问它的任何对象。 multiprocessing.Pool
使用后台线程排队对象,这违反了此规则。您可以通过将 check_same_thread=False
传递给 sqlite3.connect
:
来禁用该检查
conn = sqlite3.connect(":memory:", check_same_thread=False)
我进行更改后,您的代码 运行 没问题。没有那个改变,我看到了这个错误:
ProgrammingError: SQLite objects created in a thread can only be used in that same thread.The object was created in thread id 140082824808256 and this is thread id 140082770409216
我不确定您为什么没有看到任何错误消息;我没有得到的唯一方法是删除 for x in ITR: print x
行,因为没有它你实际上不会尝试从 Pool
检索结果,这将抑制其中发生的任何错误.
我已经尝试了所有我能想到的方法,但我无法弄清楚为什么以下多处理代码不会启动循环:
import sqlite3, itertools
# Dummy table
conn = sqlite3.connect(":memory:")
conn.execute('CREATE TABLE numbers (num integer)')
conn.executemany("INSERT INTO numbers VALUES (?)",
((x,) for x in range(5)))
conn.commit()
cmd_search = "SELECT * FROM numbers"
cursor = conn.execute(cmd_search)
def nothing(x): return x
import multiprocessing
P = multiprocessing.Pool()
#ITR = P.imap(nothing,cursor) # parallel version
ITR = itertools.imap(nothing, cursor) # serial version
for x in ITR: print x
当我 运行 使用 "serial" 版本(使用 itertools.imap
)时,我得到了 (0,) (1,) (2,) (3,) (4,)
的预期输出。使用 multiprocessing.imap
版本,我什么也没得到,循环退出。我显然与 sqlite 游标有关,切换到 cursor=range(5)
有效。
为什么多处理在这里不起作用?
默认情况下 sqlite3
不允许您在实际创建它的线程之外访问它的任何对象。 multiprocessing.Pool
使用后台线程排队对象,这违反了此规则。您可以通过将 check_same_thread=False
传递给 sqlite3.connect
:
conn = sqlite3.connect(":memory:", check_same_thread=False)
我进行更改后,您的代码 运行 没问题。没有那个改变,我看到了这个错误:
ProgrammingError: SQLite objects created in a thread can only be used in that same thread.The object was created in thread id 140082824808256 and this is thread id 140082770409216
我不确定您为什么没有看到任何错误消息;我没有得到的唯一方法是删除 for x in ITR: print x
行,因为没有它你实际上不会尝试从 Pool
检索结果,这将抑制其中发生的任何错误.