【发布时间】:2016-01-18 15:29:57
【问题描述】:
我正在尝试将 mysql 连接传递给 python 中的线程。 如果我在worker类中初始化mysql,就没有错误。
但是,连接的成本可能很高,所以我尝试只从调用函数传递 mysql 连接(参见下面的代码)。但这一直抛出这个错误:
(2006, "MySQL 服务器已消失 (BrokenPipeError(32, 'Broken 管道'))
知道为什么吗?我认为是因为我们通过mysql连接的方式
def worker(db):
""" Distributes the workload for a thread
"""
while True:
item = queue_handler.get()
perform_insert(item, db)
queue_handler.task_done()
def insert_bulk(params):
""" Handles the insert
"""
cntr = 0
res = []
cannot_read = []
(data, cms, report_id) = params
db = nmi_mysql.DB(CONFIG['earnings_db'], True)
for i in range(10):
thrd = threading.Thread(target=worker, args=(db,))
thrd.deamon = True
thrd.start()
for row in data:
split_files = row.split(',')
if len(split_files) != 34:
cannot_read.append(split_files)
continue
now = datetime.datetime.now()
res.append(<some data to insert>)
if len(res) == 750 or cntr == len(data):
queue_handler.put([res, cms, report_id])
res = []
cntr += 1
queue_handler.join()
db.close()
return [len(res), cms]
更新
我们没有传递 mysql 连接,而是创建了一个连接池并在线程中使用该池。这样,我们只需在线程级别从池中获取连接。
【问题讨论】:
-
通常情况下,不同客户端线程之间不能使用数据库连接:它们不是线程安全的。如果没有人为您提供更好的答案,我建议您将每个连接处理到同一个线程中:打开、使用和关闭。
-
@LittleSanti 我们使用了连接池。效果很好。
-
在同一个线程中完全处理每个连接时,可以使用池:获取连接、使用连接、释放连接。原因还是一样:连接通常不是线程安全的。
标签: python mysql multithreading pymysql broken-pipe