【问题标题】:Scheduler going idle under multithreading调度程序在多线程下空闲
【发布时间】:2013-07-31 14:58:23
【问题描述】:

我正在运行 Python 3.3.2、Win7/Pro、64 位,并且有一些代码试图在其自己的线程中运行调度程序。似乎当调度程序清空其工作队列时,它会进入空闲状态并且即使在队列中添加了新条目也不会恢复。从文档中我并不完全清楚它应该恢复,但我不希望用户代码(在调度程序控制之外的线程中运行)不得不担心调度程序已经“完成”的可能性.我怀疑有些东西我不理解和/或我以某种方式滥用它,但我不知道在哪里。

在下面的示例中,我通过将调度程序的 enter 方法替换为我自己的方法来解决问题,该方法检查队列长度,如果为零,则进入请求,然后再次调用调度程序的 run 方法。这似乎确实有效,但肯定感觉不对。我有什么遗漏吗?

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()

【问题讨论】:

  • self.senter() 的代码在哪里?我认为那是你真正从队列中取出一些东西的地方。需要查看它以了解实际发生的情况。
  • self.senter 是 Python Scheduler 的 enter 方法的捕获(参见 init)。
  • sched 的文档表明它在 Python 3.3 之前不是线程安全的。我猜你是那个级别的?

标签: python multithreading python-3.x scheduler


【解决方案1】:

根据docssched 将使用run() 运行所有预定的事件。文字有点晦涩,但我相信一旦所有预定事件完成,run() 就会返回。如果是这种情况,您将需要添加更多事件并再次致电run(),并根据您报告的结果,这似乎是正在发生的事情。

【讨论】:

  • 我同意这些文档与该读数并无矛盾,但我强烈希望它会在 run() 文档中被提及,并且有一些机制比自己检查队列更简单.也许代码还很年轻……
  • 至少他们提供了isEmpty() 方法来做到这一点。
猜你喜欢
  • 2021-10-15
  • 1970-01-01
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-04
相关资源
最近更新 更多