【问题标题】:Python Thread.start() throws weird exception relating to datetime.datetimePython Thread.start() 抛出与 datetime.datetime 相关的奇怪异常
【发布时间】:2013-08-27 20:17:39
【问题描述】:

我在 python 2.74 上使用 threading.Timer。这是相关的代码:

__lock = threading.Lock()
def RegeneratePopulationData():
    __lock.acquire()
    print 'I feel regenerated!'
    __lock.release()

def __setRegenerationTimer(firstTime = False):
    global __regenerationTimer
    now = _getNow().date()
    nextRun = datetime(now.year, now.month, now.day + 1, 2, 0)
    __regenerationTimer = threading.Timer((nextRun - _getNow()).total_seconds(), __setRegenerationTimer)
    print 'Regeneration timer set to run in %s' % (nextRun - _getNow())
    print __regenerationTimer.interval
    __regenerationTimer.start()
    if not firstTime:
        RegeneratePopulationData()

def _getNow():
        return datetime.now() + timedelta(hours = TIME_DIF)

这会导致从 threading.py 抛出 TypeError 异常。我已经在网上搜索了几个小时,但找不到解决方案。

将 threading.py 中的代码(出于调试目的)在第 349 行附近更改为:

            # than 20 times per second (or the timeout time remaining).
            print _time()
            print timeout
            endtime = _time() + timeout
            delay = 0.0005 # 500 us -> initial delay of 1 ms

这是我得到的例外:

Regeneration timer set to run in 2:52:12.337000
10332.337
1377634067.66
10332.337
1377634067.66
2013-08-27 21:07:47.663000
Exception in thread Thread-2:
Traceback (most recent call last):
  File "C:\Python27\lib\threading.py", line 812, in __bootstrap_inner
    self.run()
  File "C:\Python27\lib\threading.py", line 1082, in run
    self.finished.wait(self.interval)
  File "C:\Python27\lib\threading.py", line 622, in wait
    self.__cond.wait(timeout)
  File "C:\Python27\lib\threading.py", line 350, in wait
    endtime = _time() + timeout
TypeError: unsupported operand type(s) for +: 'float' and 'datetime.datetime'

我不明白为什么间隔突然变成了日期时间!

有人可以帮忙吗?

【问题讨论】:

  • 双下划线是怎么回事?你通常只在类定义中看到那些,但这段代码中没有self
  • 我打算建议您将id(self) 添加到threading.py 中的跟踪中,以查看您的程序中是否有另一个对象在等待。但是您接受了@Marin 的回答……这是否意味着问题已解决?
  • @tdelaney 这就是我最终所做的,这就是问题所在。由于我错误地将问题提出为源于 threading.py,因此我接受了这个答案,因此没有人会在这个问题上浪费时间......他的最后建议是调试,这就是我最终选择它的方式。

标签: python multithreading python-2.7


【解决方案1】:

您的代码没有显示timeout 的来源。它不是“突然变成”任何东西。无论您的代码是什么,在之前的某个时间点,datetime.datetime 被分配给timeout。要么消除这种情况,要么适当地处理它(也许通过捕获异常)。

更新:您正在修改标准库代码,这是一个糟糕的主意。您直接或间接地传递了datetime.datetime。使用pdb 找出位置。在 python 控制台中运行您的代码。当您触发异常时,请执行import pdb; pdb.pm(),然后您将进入异常位置的调试器。您可以从那里探索。

【讨论】:

  • 我的代码没有触及超时变量。我已经发布了整个相关代码。其他一切都在 threading.py 内部完成,这是 afaik 基础设施 python 代码。
  • @TalKremerman 这是一个糟糕的主意。使用内置的 python 调试器检查值,并发现 timeout 的分配位置。
  • 您的问题另有说明。是哪个?
  • 好的,我很抱歉不清楚。无论我对库代码进行微小更改,都会发生异常。对库代码的更改只是为了强调正在发生的事情。我认为发布该信息(而不是“我已调试并且...”)会使其更清晰。我似乎无法找到更改超时的位置,否则我不会发布问题。另外,我绝对不会在那里传递日期时间。从代码和输出中也可以看出这一点。
  • 大多数时候,当你非常确定某件事不可能是问题的根源时,它就是问题的根源。你确定你没有通过日期时间吗?您确定这是“相关部分”吗?你确定你没有通过编辑threading.py弄乱你的Python安装吗?
猜你喜欢
  • 2010-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-09
  • 1970-01-01
相关资源
最近更新 更多