繁体   English   中英

Python threading.Timer对象在编译为.exe时不起作用

[英]Python threading.Timer object not functioning when compiled to .exe

这是对https://stackoverflow.com/questions/37684111/ironpython-exe-file-closing-immediately-no-exception-thrown的跟进

我发现由于线程库中的Timer对象存在问题,我的程序在编译后无法正常工作。 我已将库包含在我的\\ Lib \\ site-packages目录中,并将该目录添加到程序中的路径中。 这是我正在使用的测试代码 - 一个简单的计数程序:

import sys
from threading import Timer

sys.path.append('C:\Users\[user]\Documents\Visual Studio 2015\Projects\Testing Timer Compilation issue\Testing Timer Compilation issue')
sys.path.append('C:\Users\[user]\Documents\Visual Studio 2015\Projects\Testing Timer Compilation issue\Testing Timer Compilation issue\Lib')

class Chron():
    def __init__(self):
        self.t = Timer(2, self.count)
        self.t.start()
        self.i = 0

    def count(self):
        print(self.i)
        self.i += 1
        if self.i <= 15:
            self.t = Timer(2, self.count)
            self.t.start()

c = Chron()

在Visual Studio中的Interactive Interpreter中完美运行,但是一旦我使用pyc.py编译为exe文件,它就不会运行,只需在~5秒后关闭,不会抛出任何异常。

正如前一个问题中所提到的,我有一个程序,其中包含一个我需要编译的Timer,因为源代码包含敏感凭据。 是否有任何必要的技巧使Timer在exe中工作? 它只是不兼容吗?

编辑:6天没有答案。 不幸的是,互联网上似乎没有任何资源可以解决这个特定问题。 这几乎就像我是唯一一个有这个问题的人。 这对我来说似乎很奇怪,因为问题似乎与Timer对象本身有关,我无法想象没有其他人试图在其中部署带有Timer的应用程序。 任何见解在这一点上都会有所帮助,因为我完全难过。

问题是你依靠底层的Python解释器来优雅地处理你的可执行文件的主线程终止的情况,但应该还有一些其他的仍在运行。

使用CPython或IronPython直接运行代码可以正常工作。 您创建的Timer对象实际上是Thread的特化。 解释器识别出一些非守护进程的线程仍处于活动状态,因此不会终止。 如果您不知道两种类型的线程之间的区别,请参阅文档以获取有关守护程序线程的说明。

但是,当您作为可执行文件运行时,看起来IronPython用来包装解释器的代码并不那么友好。 它只是等待主线程结束然后关闭所有内容。 尽管您的计时器被声明为非守护程序线程,但仍会发生这种情况。 可以说这是IronPython中的一个错误。

因此,解决方案是在Timer线程仍在运行时让主线程运行。 对此示例代码执行此操作的最简单方法就是睡眠 - 例如:

import sys
sys.path.append(r"c:\Program Files (x86)\IronPython 2.7\Lib")
from threading import Timer
from time import sleep

class Chron():
    def __init__(self):
        self.t = Timer(2, self.count)
        self.t.start()
        self.i = 0

    def count(self):
        print(self.i)
        self.i += 1
        if self.i <= 15:
            self.t = Timer(2, self.count)
            self.t.start()

c = Chron()
sleep(35)

但是,对于更复杂的应用程序,您应该考虑线程之间的一些通信以协调何时关闭 - 例如使用join()来等待线程终止。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM