2013-07-31 49 views
1

我运行的Python 3.3.2中,Win7版/专业版,64位会闲置,有一些代码中,我试图运行在自己的线程调度器。看起来,当调度程序清空其工作队列时,即使在将新条目添加到队列中时,它也会空闲并不会恢复。这不是从它应该恢复文档我完全显而易见的,但我不希望用户代码(在调度的控制之外的线程中运行)来担心的是,调度器“已完成”的可能性。我怀疑有些事情我不理解和/或我以某种方式滥用它,但我不知道在哪里。调度下多线程

在下面的例子中,我通过更换调度程序的与我自己的输入方法,该方法检查队列长度,并且如果它是零,进入请求,然后再次调用调度程序的运行方法解决了这个问题。这似乎工作,但肯定感觉不对。有什么我失踪?

class A(threading.Thread): 
    def __init__(self): 
     super().__init__() 
     self.schedControl = sched.scheduler(time.time, time.sleep) 
     self.senter = self.schedControl.enter 
     self.schedControl.enter = self.enter 
    def print_time(self, a=''): 
     """Print current time and optional message.""" 
     tmx = time.time() 
     tms = time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime(tmx)) 
     print("{0}: {1}".format(tms, a)) 
    def run(self): 
     #for call by thread's start method 
     self.schedControl.run() 

    def enter(self, *args, **kwargs): 
     tmp = False 
     if len([x for x in self.schedControl.queue]) == 0: 
      tmp = True 
     self.senter(*args, **kwargs) 
     if tmp: 
      print("Restart") 
      self.schedControl.run() 

class B(object): 
    def __init__(self): 
     self.scheduler = A() 
     self.itemCount = 0 
     self.scheduler.schedControl.enter(1, 1, self.scheduler.print_time, argument=('Starting Scheduler',)) 
     self.scheduler.start() 

    def newItem(self): 
     self.scheduler.schedControl.enter(1, 1, self.scheduler.print_time, argument=('New Item: {0}'.format(self.itemCount),)) 
     self.itemCount += 1 
foo = B() 
foo.newItem() 
time.sleep(5) 
foo.newItem() 
time.sleep(5) 
foo.newItem() 
time.sleep(5) 
foo.newItem() 
time.sleep(5) 
foo.newItem() 
print("Going to sleep") 
time.sleep(100) 
sys.exit() 
+0

哪里是'self.senter()'的代码?我认为那是你真正从队列中取出某些东西的地方。需要查看它以了解实际发生的情况。 – Jonathan

+0

self.senter是Python Scheduler的enter方法的捕获(请参阅__init__)。 – user1104605

+0

'sched'的文档表明它在Python 3.3之前不是线程安全的。我认为你在那个水平? – Jonathan

回答

0

按照docssched将运行所有预定的事件与run()。该文本有点模糊,但我相信run()返回所有预定事件完成后。如果是这样的话,你将需要添加更多的事件,并再次呼吁run(),这似乎是发生了什么事给你报告的结果。

+0

我同意文档是无法与阅读不一致,但我会强烈预期它在run()文档被提及,并有一定的机制比自己检查队列使其更简单。也许代码只是年轻... – user1104605

+0

至少他们提供'isEmpty()'方法来做到这一点。 – Jonathan