由于线程库中的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的应用程序。任何见解在这一点上都会有所帮助,因为我完全被难倒了。
答案 0 :(得分:5)
问题在于你依靠底层的Python解释器来优雅地处理你的可执行文件的主线程已经终止的情况,但是应该还有一些其他的仍在运行。
使用CPython或IronPython直接运行代码按预期工作。您创建的Timer对象实际上是Thread的特化。解释器认识到有一些非守护进程 线程仍处于活动状态,因此不会终止。如果您不知道两种类型的线程之间的区别,请参阅the docs以获取有关守护程序线程的说明。
但是,当您作为可执行文件运行时,看起来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()等待线程终止。