Python 线程 - 访问 PostgreSQL 时崩溃
这里有一个简单的多线程程序,运行得很好:
import psycopg2
import threading
import time
class testit(threading.Thread):
def __init__(self, currency):
threading.Thread.__init__(self)
self.currency = currency
def run(self):
global SQLConnection
global cursor
SQLString = "Select dval from ddata where dname ='%s' and ddate = '2009-07-17'" \
%self.currency
z = time.time()
while (time.time() - z) < 2:
print SQLString
SQLConnection = psycopg2.connect(database = "db", user = "xxxx", password = "xxxx")
cursor = SQLConnection.cursor()
a = testit('EURCZK')
b = testit('EURPLN')
a.start()
b.start()
但是,一旦我尝试在线程中访问postgresql数据库,使用以下代码时,我总是会遇到崩溃的问题:
import psycopg2
import threading
import time
class testit(threading.Thread):
def __init__(self, currency):
threading.Thread.__init__(self)
self.currency = currency
def run(self):
global SQLConnection
global cursor
SQLString = "Select dval from ddata where dname ='%s'and ddate = '2009-07-17'" %self.currency
z = time.time()
while (time.time() - z) < 2:
cursor.execute(SQLString)
print cursor.fetchall()
SQLConnection = psycopg2.connect(database = "db", user = "xxxx", password = "xxxx")
cursor = SQLConnection.cursor()
a = testit('EURCZK')
b = testit('EURPLN')
a.start()
b.start()
这两者之间唯一的区别在于while循环。我对多线程编程还比较陌生。请问postgres库(psycopg2)是不是不“线程安全”?这一切都是在Windows XP上运行的。我能做些什么呢?
谢谢。
2 个回答
0
太好了,问题解决了。之前有人给出了一个答案,但后来似乎把它删掉了,答案是给每个线程分配一个独立的连接。果然,这样做就解决了问题。所以这段代码可以正常运行:
import psycopg2
import threading
import time
class testit(threading.Thread):
def __init__(self, currency):
threading.Thread.__init__(self)
self.currency = currency
self.SQLConnection = psycopg2.connect(database = "db", user = "xxxx", password = "xxxx")
self.cursor = self.SQLConnection.cursor()
def run(self):
SQLString = "Select dval from ddata where dname ='%s' and ddate = '2009-07-17'" \
%self.currency
z = time.time()
while (time.time() - z) < 2:
self.cursor.execute(SQLString)
print self.cursor.fetchall()
a = testit('EURCZK')
b = testit('EURPLN')
a.start()
b.start()
2
global SQLConnection
global cursor
看起来你是在多个线程中访问全局变量?你绝对不应该这样做,除非这些全局变量是线程安全的,或者你自己提供了合适的锁定机制。
现在你有两个线程在同时访问同一个连接和同一个游标,它们会互相干扰。虽然psycopg2的连接可能是线程安全的,但游标却不是。
每个线程应该使用一个游标(可能也要使用一个连接)。