python多线程读取数据库数据_Python基于多线程操作数据库相关知识点详解
Python基于多線程操作數據庫相關問題分析
本文實例分析了Python多線程操作數據庫相關問題。分享給大家供大家參考,具體如下:
python多線程并發操作數據庫,會存在鏈接數據庫超時、數據庫連接丟失、數據庫操作超時等問題。
解決方法:使用數據庫連接池,并且每次操作都從數據庫連接池獲取數據庫操作句柄,操作完關閉連接返回數據庫連接池。
*連接數據庫需要設置charset = 'utf8', use_unicode = True,不然會報中文亂碼問題
*網上說解決python多線程并發操作數據庫問題,連接時使用self.conn.ping(True)(檢查并保持長連接),但是我這邊親測無法解決,建議還是使用數據庫連接池
python多線程代碼:
import threading
class MyThread(threading.Thread):
def __init__(self, name, count, exec_object):
threading.Thread.__init__(self)
self.name = name
self.count = count
self.exec_object = exec_object
def run(self):
while self.count >= 0:
count = count - 1
self.exec_object.execFunc(count)
thread1 = MyThread('MyThread1', 3, ExecObject())
thread2 = MyThread('MyThread2', 5, ExecObject())
thread1.start()
thread2.start()
thread1.join() # join方法 執行完thread1的方法才繼續主線程
thread2.join() # join方法 執行完thread2的方法才繼續主線程
# 執行順序 并發執行thread1 thread2,thread1和thread2執行完成才繼續執行主線程
# ExecObject類是自定義數據庫操作的業務邏輯類
#
########join方法詳解########
thread1 = MyThread('MyThread1', 3, ExecObject())
thread2 = MyThread('MyThread2', 5, ExecObject())
thread1.start()
thread1.join() # join方法 執行完thread1的方法才繼續主線程
thread2.start()
thread2.join() # join方法 執行完thread2的方法才繼續主線程
# 執行順序 先執行thread1,執行完thread1再執行thread2,執行完thread2才繼續執行主線程
mysql數據庫連接池代碼:
import MySQLdb
from DBUtils.PooledDB import PooledDB
class MySQL:
host = 'localhost'
user = 'root'
port = 3306
pasword = ''
db = 'testDB'
charset = 'utf8'
pool = None
limit_count = 3 # 最低預啟動數據庫連接數量
def __init__(self):
self.pool = PooledDB(MySQLdb, self.limit_count, host = self.host, user = self.user, passwd = self.pasword, db = self.db,
port = self.port, charset = self.charset, use_unicode = True)
def select(self, sql):
conn = self.pool.connection()
cursor = conn.cursor()
cursor.execute(sql)
result = cursor.fetchall()
cursor.close()
conn.close()
return result
def insert(self, table, sql):
conn = self.pool.connection()
cursor = conn.cursor()
try:
cursor.execute(sql)
conn.commit()
return {'result':True, 'id':int(cursor.lastrowid)}
except Exception as err:
conn.rollback()
return {'result':False, 'err':err}
finally:
cursor.close()
conn.close()
更多關于Python相關內容感興趣的讀者可查看本站專題:《Python進程與線程操作技巧總結》、《Python數據結構與算法教程》、《Python函數使用技巧總結》、《Python字符串操作技巧匯總》、《Python入門與進階經典教程》、《Python+MySQL數據庫程序設計入門教程》及《Python常見數據庫操作技巧匯總》
希望本文所述對大家Python程序設計有所幫助。
Python多線程原理與用法實例剖析
本文實例講述了Python多線程原理與用法。分享給大家供大家參考,具體如下:
先來看個栗子:
下面來看一下I/O秘籍型的線程,舉個栗子——爬蟲,下面是爬下來的圖片用4個線程去寫文件
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re
import urllib
import threading
import Queue
import timeit
def getHtml(url):
html_page = urllib.urlopen(url).read()
return html_page
# 提取網頁中圖片的URL
def getUrl(html):
pattern = r'src="(http://img.*?)"' # 正則表達式
imgre = re.compile(pattern)
imglist = re.findall(imgre, html) # re.findall(pattern,string) 在string中尋找所有匹配成功的字符串,以列表形式返回值
return imglist
class getImg(threading.Thread):
def __init__(self, queue, thread_name=0): # 線程公用一個隊列
threading.Thread.__init__(self)
self.queue = queue
self.thread_name = thread_name
self.start() # 啟動線程
# 使用隊列實現進程間通信
def run(self):
global count
while (True):
imgurl = self.queue.get() # 調用隊列對象的get()方法從隊頭刪除并返回一個項目
urllib.urlretrieve(imgurl, 'E:\mnt\girls\%s.jpg' % count)
count += 1
if self.queue.empty():
break
self.queue.task_done() # 當使用者線程調用 task_done() 以表示檢索了該項目、并完成了所有的工作時,那么未完成的任務的總數就會減少。
imglist = []
def main():
global imglist
url = "http://huaban.com/favorite/beauty/" # 要爬的網頁地址
html = getHtml(url)
imglist = getUrl(html)
def main_1():
global count
threads = []
count = 0
queue = Queue.Queue()
# 將所有任務加入隊列
for img in imglist:
queue.put(img)
# 多線程爬去圖片
for i in range(4):
thread = getImg(queue, i)
threads.append(thread)
# 阻塞線程,直到線程執行完成
for thread in threads:
thread.join()
if __name__ == '__main__':
main()
t = timeit.Timer(main_1)
print t.timeit(1)
4個線程的執行耗時為:0.421320716723秒
修改一下main_1換成單線程的:
def main_1():
global count
threads = []
count = 0
queue = Queue.Queue()
# 將所有任務加入隊列
for img in imglist:
queue.put(img)
# 多線程爬去圖片
for i in range(1):
thread = getImg(queue, i)
threads.append(thread)
# 阻塞線程,直到線程執行完成
for thread in threads:
thread.join()
單線程的執行耗時為:1.35626623274秒
再來看一個:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import threading
import timeit
def countdown(n):
while n > 0:
n -= 1
def task1():
COUNT = 100000000
thread1 = threading.Thread(target=countdown, args=(COUNT,))
thread1.start()
thread1.join()
def task2():
COUNT = 100000000
thread1 = threading.Thread(target=countdown, args=(COUNT // 2,))
thread2 = threading.Thread(target=countdown, args=(COUNT // 2,))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
if __name__ == '__main__':
t1 = timeit.Timer(task1)
print "countdown in one thread ", t1.timeit(1)
t2 = timeit.Timer(task2)
print "countdown in two thread ", t2.timeit(1)
task1是單線程,task2是雙線程,在我的4核的機器上的執行結果:
countdown in one thread 3.59939150155
countdown in two thread 9.87704289712
天吶,雙線程比單線程計算慢了2倍多,這是為什么呢,因為countdown是CPU密集型任務(計算嘛)
I/O密集型任務:線程做I/O處理的時候會釋放GIL,其他線程獲得GIL,當該線程再做I/O操作時,又會釋放GIL,如此往復;
CPU密集型任務:在多核多線程比單核多線程更差,原因是單核多線程,每次釋放GIL,喚醒的哪個線程都能獲取到GIL鎖,所以能夠無縫執行(單核多線程的本質就是順序執行),但多核,CPU0釋放GIL后,其他CPU上的線程都會進行競爭,但GIL可能會馬上又被CPU0(CPU0上可能不止一個線程)拿到,導致其他幾個CPU上被喚醒后的線程會醒著等待到切換時間后又進入待調度狀態,這樣會造成線程顛簸(thrashing),導致效率更低。
更多關于Python相關內容感興趣的讀者可查看本站專題:《Python進程與線程操作技巧總結》、《Python數據結構與算法教程》、《Python函數使用技巧總結》、《Python字符串操作技巧匯總》、《Python入門與進階經典教程》、《Python+MySQL數據庫程序設計入門教程》及《Python常見數據庫操作技巧匯總》
希望本文所述對大家Python程序設計有所幫助。
以上就是本次給大家分享的關于java的全部知識點內容總結,大家還可以在下方相關文章里找到相關文章進一步學習,感謝大家的閱讀和支持。
總結
以上是生活随笔為你收集整理的python多线程读取数据库数据_Python基于多线程操作数据库相关知识点详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: k8s 手动恢复redis 集群_二进制
- 下一篇: 简述python解释器的作用_什么是py