2010-05-18 78 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代替。)