python中多线程应用程序中的分段错误错误

Sha*_*s88 0 python multithreading mysql-python

我在python中有一个多线程应用程序,其中我创建了多个生产者线程,并从数据库中提取数据.数据以块的形式提取.因此,线程创建带有限制值的sql语句的部分将保持在锁定状态.为了让线程同时执行查询,query()函数保持在锁外.然后,结果获取部分再次保持在锁定之下.以下是代码段:

with UserAgent.lock:
    sqlGeoTarget = "call sp_ax_ari_select_user_agent_list('0'," + str(self.chunkStart) + "," + str(self.chunkSize) + ",1);"
    self.chunkStart += self.chunkSize

self.dbObj.query(sqlGeoTarget)
print "query executed. Processing data now..."+sqlGeoTarget

with UserAgent.lock:
    result = self.dbObj.fetchAll()
    self.dbObj.dbCursor.close()
Run Code Online (Sandbox Code Playgroud)

但是这段代码会产生致命的错误segmentation fault (core dumped).因为如果我将所有代码置于锁定状态,它就可以正常执行.我在获取数据后显式关闭游标,当query()函数再次触发时重新打开它.

此代码位于名为的类中UserAgent,它是名为的类的共享资源Producer.因此,共享数据库对象.所以问题区域99%必须是因为db对象被共享同时命中查询并且关闭游标然后必须弄乱结果集.但那么如何解决这个问题并实现并发数据库查询执行?

Mar*_*ers 5

不要跨线程重用连接.而是为每个线程创建一个新连接.

从MySQLdb用户指南:

MySQL协议无法一次使用同一连接处理多个线程.一些早期版本的MySQLdb利用锁定来实现2的线程安全.虽然使用标准的Cursor类(使用mysql_store_result()它)并不是非常难以实现,但SSCursor(使用mysql_use_result()后者)很复杂,后者必须确保所有行可以执行另一个查询之前已经阅读.它是通过加入交易的进一步复杂化,因为交易当光标执行查询开始,但结束时COMMITROLLBACK由Connection对象执行.除了在查询执行期间无法共享它之外,两个线程在事务正在进行时根本无法共享连接.这使得代码过于复杂,以至于它不值得.

这样做的一般结果是:不要在线程之间共享连接.这真的不值得你或我的努力,最终,可能会损害性能,因为MySQL服务器为每个连接运行一个单独的线程.您当然可以执行缓存池中的连接等操作,并一次将这些连接提供给一个线程.如果让两个线程同时使用连接,那么MySQL客户端库可能会崩溃并死掉.你被警告了.

强调我的.

请改用线程本地存储专用连接池库.