#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date : 2018-04-25 18:04:06
# @Author : Your Name ([email protected])
# @Link : http://example.org
# @Version : $Id$
import threading,time,MySQLdb
class TestMysql():
def __init__(self, ip, port, username, password, database):
self.db = MySQLdb.connect(host=ip, port=port, user=username, passwd=password, db=database, charset="utf8")
self.cursor = self.db.cursor()
def select1(self,tablename):
sql = "SELECT (gender & 15) AS gender1, f.image_data,f.json FROM intellif_face." + tablename + " f limit 100000;"
self.cursor.execute(sql)
data = self.cursor.fetchone()
print(data)
def select2(self,tablename):
sql = "SELECT (race & 15) AS race1,f.image_data,f.json FROM intellif_face." + tablename + " f limit 100000;"
self.cursor.execute(sql)
data = self.cursor.fetchone()
print(data)
if __name__ == '__main__':
test = TestMysql("192.168.11.128", 3306, "root", 'introcks1234', "intellif_face")
tablelist = ['t_face_24','t_face_25','t_face_26'] # 可以增加表名
thread = []
for tablename in tablelist:
print(tablename)
t1 = threading.Thread(target = test.select1, args = (tablename,))
t2 = threading.Thread(target = test.select2, args = (tablename,))
thread.append(t1)
thread.append(t2)
for t in thread:
t.setDaemon(True)
t.start()
t.join()
============================output=========================================
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Python36\lib\threading.py", line 916, in _bootstrap_inner
self.run()
File "C:\Python36\lib\threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "F:\code\pyProject\thread\thread_mysql_test.py", line 25, in select2
self.cursor.execute(sql)
File "C:\Python36\lib\site-packages\MySQLdb\cursors.py", line 250, in execute
self.errorhandler(self, exc, value)
File "C:\Python36\lib\site-packages\MySQLdb\connections.py", line 50, in defaulterrorhandler
raise errorvalue
File "C:\Python36\lib\site-packages\MySQLdb\cursors.py", line 247, in execute
res = self._query(query)
File "C:\Python36\lib\site-packages\MySQLdb\cursors.py", line 411, in _query
rowcount = self._do_query(q)
File "C:\Python36\lib\site-packages\MySQLdb\cursors.py", line 374, in _do_query
db.query(q)
File "C:\Python36\lib\site-packages\MySQLdb\connections.py", line 277, in query
_mysql.connection.query(self, query)
_mysql_exceptions.OperationalError: (2013, 'Lost connection to MySQL server during query')
.......
[Finished in 1.9s with exit code 3221226356]
1
ericls 2018-04-25 20:32:25 +08:00 via iPhone
执行前检查是否需要重新连接 如果需要就重新连接
|
2
tkmiles 2018-04-25 20:37:04 +08:00
我貌似记得 mysql 会杀死空闲连接的
|
4
testsec 2018-04-25 21:45:36 +08:00 via iPhone
用连接池
|
5
Aliencn 2018-04-25 21:50:44 +08:00
数据库承受不住这么大的查询吧,把 sql 语句的 limit 改成 1 试试。
|
6
lesteryu 2018-04-25 21:57:34 +08:00
MySQLdb 的 connections 和 cursors 都不 thread safe,不同的 threads 不能用同一个 connection 或者 cursor。
|
7
MerleLiuKun 2018-04-26 08:49:13 +08:00 via Android
check connection 可以用 ping(). 感觉可以用 MySQLdb 提供的 pool.
|
10
xpresslink 2018-04-26 09:16:11 +08:00
要每个线程单独用一个 连接,把 test = TestMysql("192.168.11.128", 3306, "root", 'introcks1234', "intellif_face")
放在 for 里面就可以了 if __name__ == '__main__': □□□□tablelist = ['t_face_24','t_face_25','t_face_26'] # 可以增加表名 □□□□thread = [] □□□□for tablename in tablelist: □□□□□□□□test = TestMysql("192.168.11.128", 3306, "root", 'introcks1234', "intellif_face") □□□□□□□□print(tablename) □□□□□□□□t1 = threading.Thread(target = test.select1, args = (tablename,)) □□□□□□□□t2 = threading.Thread(target = test.select2, args = (tablename,)) □□□□□□□□thread.append(t1) □□□□□□□□thread.append(t2) □□□□for t in thread: t.setDaemon(True) t.start() □□□□t.join() |
11
Hopetree 2018-04-26 09:24:59 +08:00
借楼问一下,往 MySQL 里面插入多个数据的做法,有两种做法①开启一个连接,然后循环插入数据,最后断开连接②循环(开启连接,插入,断开)这个步骤,也就是每次插入都重新练级,我一直有点疑惑这两种方式,从性能和安全等给方面考虑,应该是采取哪一种?我用 Python 的时候喜欢用第一种,里面使用 try 语句来插入
|
12
wsds OP @xpresslink 那就是要每个方法中各设各的连接咯,偷懒放到 init 里边,看来还是得独立出来
|
13
xpresslink 2018-04-26 09:52:34 +08:00
@wsds
这个只是临时方案,连接太多数据库也受不了, 而且每个线程创建了连接要关闭。不然时间长了爆内存了。 实际上你应该弄个连接池,每个线程到连接池取一个打开的连接,超过连接数就等待。 连接最后在退出时候统一关闭。 |
14
wsds OP @xpresslink 连接池怎么搞?
|
17
Minys 2018-04-27 00:11:10 +08:00 via iPhone
@xpresslink 自己写的线程池操作也可能有意想不到的危险,因为 Python 的 GIL,多线程的时候其实是通过 CPU 不断切换执行,让用户看起来像多线程。这就会出现 thread1 和 thread2 在对同一个对象操作的时候出现问题。
比如两个 thread1 和 thread2 都要执行对 A.a+=1 的操作,但是这个看似基本的操作其实分 3 步: 1. tmp=getattr(A, 'a') 2. tmp =tmp+1 3. setattr(A, 'a', tmp) 如果刚好在这中间切换线程,就会导致奇怪的 bug,根本无法 debug,感觉还是使用 multiprocessing 里面的 Pool 来直接多进程操作比较好。多线程的话还是得用 threading 库确保不会冲突,必要的时候还是得上锁。 |
18
sujin190 2018-04-27 20:27:02 +08:00
首先 MySQLdb 并不是线程安全的,而且 mysql 协议是 request respond 模式的,并不能在上一个查询未完成之前发送下一个查询请求,这种基础问题随便一查都知道的吧,多线程不加锁挂才是正常的
|