在atexit中引用其他模块

发布于 2024-08-27 13:21:54 字数 743 浏览 6 评论 0原文

我有一个函数负责在程序结束时杀死子进程:

class MySingleton:
    def __init__(self):
        import atexit
        atexit.register(self.stop)

    def stop(self):
        os.kill(self.sel_server_pid, signal.SIGTERM)

但是,当调用此函数时,我收到一条错误消息:

Traceback (most recent call last):
File "/usr/lib/python2.5/atexit.py", line 24, in _run_exitfuncs
   func(*targs, **kargs)
File "/home/commando/Development/Diploma/streaminatr/stream/selenium_tests.py", line 66, in stop
   os.kill(self.sel_server_pid, signal.SIGTERM)
AttributeError: 'NoneType' object has no attribute 'kill'

看起来像 os 和 signal 模块在调用 atexit 之前卸载。重新导入它们可以解决问题,但这种行为对我来说似乎很奇怪 - 这些模块是在我注册处理程序之前导入的,那么为什么它们在我自己的退出处理程序运行之前被卸载呢?

I have a function that is responsible for killing a child process when the program ends:

class MySingleton:
    def __init__(self):
        import atexit
        atexit.register(self.stop)

    def stop(self):
        os.kill(self.sel_server_pid, signal.SIGTERM)

However I get an error message when this function is called:

Traceback (most recent call last):
File "/usr/lib/python2.5/atexit.py", line 24, in _run_exitfuncs
   func(*targs, **kargs)
File "/home/commando/Development/Diploma/streaminatr/stream/selenium_tests.py", line 66, in stop
   os.kill(self.sel_server_pid, signal.SIGTERM)
AttributeError: 'NoneType' object has no attribute 'kill'

Looks like the os and signal modules get unloaded before atexit is called. Re-importing them solves the problem, but this behaviour seems weird to me - these modules are imported before I register my handler, so why are they unloaded before my own exit handler runs?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

面犯桃花 2024-09-03 13:21:54

对于程序终止时销毁事物的顺序没有强有力的保证,因此最好确保 atexit 注册的函数是自包含的。例如,在您的情况下:

class MySingleton:
    def __init__(self):
        import atexit
        atexit.register(self.stop)
        self._dokill = os.kill
        self._thesig = signal.SIGTERM

    def stop(self):
        self._dokill(self.sel_server_pid, self._thesig)

这比重新导入模块更可取(可以想象,这可能会导致程序终止速度减慢,甚至无休止的循环,尽管对于“系统提供的”模块(例如 os )来说,这种风险较小)。

There are no strong guarantees about the order in which things are destroyed at program termination time, so it's best to ensure atexit-registered functions are self contained. E.g., in your case:

class MySingleton:
    def __init__(self):
        import atexit
        atexit.register(self.stop)
        self._dokill = os.kill
        self._thesig = signal.SIGTERM

    def stop(self):
        self._dokill(self.sel_server_pid, self._thesig)

This is preferable to re-importing modules (which could conceivably cause slowdown of program termination and even unending loops, though that risk is lesser for "system-supplied" modules such as os).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文