Python中的cx_Oracle,生成器和线程
作者:互联网
当连接对象被不同的线程使用时,cx_Oracle游标的行为是什么?发电机会如何影响这种行为?特别…
编辑:原始示例函数不正确;子函数返回一个生成器,在循环中没有直接使用yield.这澄清了何时执行(返回后),但仍然不回答是否可以使用游标,如果另一个线程开始使用创建游标的连接对象.它实际上似乎(在python 2.4中,至少),尝试…最终与yield导致语法错误.
def Get()
conn = pool.get()
try:
cursor = conn.cursor()
cursor.execute("select * from table ...")
return IterRows(cursor)
finally:
pool.put(conn)
def IterRows(cursor):
for r in cursor:
yield r
Get()是一个由多个线程调用的函数.使用threaded = False参数创建连接.
我在想…
>如果线程2出现并使用相同的连接对象,线程1的游标对象是否仍然可用?如果没有,会发生什么?
我所看到的行为是cx_Oracle中关于协议错误的异常,然后是段错误.
解决方法:
见the docs:threadsafety是,我引用,
Currently 2, which means that threads
may share the module and connections,
but not cursors.
所以你的“游标池”构造(其中一个游标可能由不同的线程使用)似乎超出了线程安全级别.这不是共享连接的问题(因为你已经在连接的构造函数中正确地传递了线程,所以没关系)但是游标.您可能希望在线程第一次使用它之后将每个游标存储在threading.local中,这样每个线程都可以拥有自己的1-cursor“池”(不是键优化,但是:使新游标不是重型作业).
在你的问题2中,finally子句在生成器对象(通过调用生成器函数Get构建)全部完成时执行 – 要么是因为它提升了StopIteration,要么是因为它被垃圾收集(通常是因为它的最后引用有刚走了例如,如果呼叫者是:
def imthecaller():
for i, row in enumerate(Get()):
print i, row
if i > 1: break
# this is the moment the generators' finally-clause runs
print 'bye'
最后执行(最多)3行已经产生.
标签:python,generator,yield,multithreading,cx-oracle 来源: https://codeday.me/bug/20190705/1385252.html