2014-10-29 19 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