2014-10-29 108 views
3

我写了一个Python程序是这样应该在多线程模式下运行:Python和sqlite3.ProgrammingError:递归使用游标不允许

def Func(host,cursor,db): 

    cursor.execute('''SELECT If_index, Username, Version, Community, Ip_traff FROM HOST WHERE 
    Hostname = ?''',(host,)) 

    #do something 

#--- Main --- 

db = sqlite3.connect(os.getcwd()+'\HOST', check_same_thread = False) #opendatabase  
cursor = db.cursor()             #generate a cursor 

for ii in range(len(host)): #host is a list of ipaddress 

    #for each host i want generate a thread 
    thr = threading.Thread(target = Func, args=(host[ii],cursor,db) 
    thr.start() 

我收到sqlite3.ProgrammingError:递归使用游标不允许的。在这种情况下,我如何管理sqlite3的递归游标? 非常感谢 保罗

+0

为什么你不给每个线程自己的光标? – 2014-10-29 13:14:18

回答

3

好了,事情是sqlite3的模块不喜欢多线程的情况下,你可以看到sqlite3的模块的文档中

...the Python module disallows sharing connections and cursors between threads[1]

我会做的是使用某种在Func函数中同步,例如一个threading.Lock [2]。你Func键看起来就像这样:

# Define the lock globally 
lock = threading.Lock() 

def Func(host,cursor,db): 
    try: 
     lock.acquire(True) 
     res = cursor.execute('''...''',(host,)) 
     # do something 
    finally: 
     lock.release() 

上面的代码将通过让一个线程需要锁的cursor.execute的执行进行同步,其他线程将等待,直到它的释放,而锁的线程时完成后,它释放锁以供其他人使用。

这应该解决问题。

[1] https://docs.python.org/2/library/sqlite3.html#multithreading

[2] https://docs.python.org/2/library/threading.html?highlight=threading#rlock-objects

+0

谢谢似乎工作! – 2014-10-30 11:05:27

+0

我用锁:代替尝试,最后(更紧凑)谢谢:) – 2014-10-30 14:33:28