【问题标题】:Python threads - crashing when they access postgreSQLPython线程-访问postgreSQL时崩溃
【发布时间】:2010-11-12 00:43:50
【问题描述】:

这是一个运行良好的简单线程程序:

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 上运行。有什么我能做的吗?

谢谢。

【问题讨论】:

  • psycopg 可以做到这一点。您收到的确切错误消息是什么?
  • 没有错误信息 Christopher - 只有一个大窗口停止标志它无法读取某些内存位置。因此,适当的系统级崩溃。我将尝试为每个线程提供自己的连接和光标。
  • 嗯。好的。好吧,free-soft.org/FSM/english/issue01/fog.html 表明您最初的尝试是有效的。也许这在 v2 中有所改变。

标签: python postgresql


【解决方案1】:

宾果它正在工作。有人留下了答案,但随后似乎已将其删除,以便为每个线程提供自己的连接。是的,这解决了它。所以这段代码有效:

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()

【讨论】:

  • 我留下了原来的答案,但是当我在 psycopg 的文档中读到你应该能够做你想做的事情时我删除了。 :-)
  • 不需要保护连接。查看psycopg2.threadsafety 的值,以及here 的含义。
  • 这个例子:initd.org/svn/psycopg/psycopg2/trunk/examples/threads.py 也表明你应该能够做你正在尝试的事情。无论如何,即使您不能为所有线程建立一个连接,您也可能想尝试使用连接池。
【解决方案2】:
global SQLConnection
global cursor

您似乎正在从多个线程访问全局变量?您应该永远不要这样做,除非这些全局变量是线程安全的,或者您自己提供了适当的锁定。

您现在有 2 个线程访问同一个连接和同一个游标。他们会踩到对方的脚趾。 psycopg2 连接可能是线程安全的,但游标不是。

每个线程使用一个游标(也可能是一个连接)。

【讨论】:

  • 知道了。当您回答时,我发现了我的方式的错误。看我自己的答案。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-06
  • 1970-01-01
  • 2014-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多