2010-05-18 57 views
1

我有一個python腳本運行一個特定的腳本大量的次數(蒙特卡洛目的),我已經腳本的方式是,我排隊腳本所需的次數,它應該運行,然後我產生線程並且每個線程在完成時一次又一次地運行腳本。Python 2.5中的線程問題,KeyError:51,幫助調試?

一旦特定線程中的腳本完成後,通過訪問一個鎖將輸出寫入文件(所以我猜測只有一個線程在給定時間訪問鎖)。一旦鎖由一個線程釋放,下一個線程訪問它並將其輸出添加到先前寫入的文件並重寫它。

我沒有面臨一個問題,當迭代次數是像10或20小,但是當它像50或150大,python返回一個KeyError:51告訴我元素不存在,並指出錯誤是在我困惑的鎖,因爲只有一個線程應該立即訪問鎖,我不希望有錯誤。

這是我使用的類:

class errorclass(threading.Thread): 

    def __init__(self, queue): 
     self.__queue=queue 
     threading.Thread.__init__(self) 

    def run(self): 
     while 1: 
       item = self.__queue.get() 
       if item is None: break 
       result = myfunction() 
       lock = threading.RLock() 
       lock.acquire() 
       ADD entries from current thread to entries in file and 
       REWRITE FILE 
       lock.release() 

queue = Queue.Queue() 

for i in range(threads): 
    errorclass(queue).start() 

for i in range(desired iterations): 
    queue.put(i) 
for i in range(threads): 
    queue.put(None) 

Python和KeyError異常返回:51後鎖訪問添加/寫文件操作過程中大量需要的迭代,我想知道如果這是正確的方式使用鎖定,因爲每個線程都有鎖定操作,而不是每個線程訪問共享鎖定?怎樣才能糾正這個問題呢?

回答

0

創建鎖並將其傳遞到errorclass.__init__,以便它們共享一個實例。否則,每個線程都將自己鎖定在重新進入他們自己的臨界區域之外,這完全沒有任何操作。

1

你現在所擁有的是什麼每個線程的run方法新鎖爲每迭代。實際上,根本沒有鎖定。如果要保護寫入文件,則需要確保訪問同一文件的線程使用相同的鎖對象。要做到這一點,最簡單的方法是在全球層面來創建它:

lock = threading.RLock() 
class errorclass(...): 
    ... 
    def run(self) 
     ... # get items and process 
     with lock: 
      ADD entries from current thread to entries in file and REWRITE FILE 

你需要使用from __future__ import with_statement使用with語句在Python 2.5,但它可以確保你永遠不會忘記以解除鎖定,即使發生錯誤也沒有。 (如果您需要Python 2.4及更早版本的兼容性,則必須使用try/finally代替。)