Python:Django:信号处理程序和主线程

发布于 2024-12-22 13:30:41 字数 186 浏览 3 评论 0原文

我正在构建一个 django 应用程序,它依赖于已实现 SIGINT 信号处理程序的 python 模块。

假设我无法更改我所依赖的模块,如何解决将其集成到 Django 中的“信号仅在主线程中工作”错误?

我可以在 Django 主线程上运行它吗? 有没有办法禁止处理程序以允许模块在非主线程上运行?

谢谢!

I am building a django application which depends on a python module where a SIGINT signal handler has been implemented.

Assuming I cannot change the module I am dependent from, how can I workaround the "signal only works in main thread" error I get integrating it in Django ?

Can I run it on the Django main thread?
Is there a way to inhibit the handler to allow the module to run on non-main threads ?

Thanks!

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

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

发布评论

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

评论(4

奢欲 2024-12-29 13:30:41

Django 的内置开发服务器默认启用自动重新加载功能,该功能会生成一个新线程作为重新加载代码的方式。要解决此问题,您可以简单地执行以下操作,尽管您显然会失去自动重新加载的便利:

python manage.py runserver --noreload

在选择生产设置时,您还需要注意这一点。至少某些部署选项(例如线程 fastcgi)肯定会在主线程之外执行代码。

Django's built-in development server has auto-reload feature enabled by default which spawns a new thread as a means of reloading code. To work around this you can simply do the following, although you'd obviously lose the convenience of auto-reloading:

python manage.py runserver --noreload

You'll also need to be mindful of this when choosing your production setup. At least some of the deployment options (such as threaded fastcgi) are certain to execute your code outside main thread.

寒江雪… 2024-12-29 13:30:41

我在项目中使用Python 3.5和Django 1.8.5,最近遇到了类似的问题。我可以轻松地直接使用 SIGNAL 运行我的 xxx.py 代码,但由于错误“signal only”,它无法作为包在 Django 上执行在主线程中工作”。

首先,带有 --noreload --nothreading 的 runserver 是可用的,但它运行我的多线程代码对我来说太慢了。

其次,我发现我的包的 __init__.py 中的代码在主线程中运行。但是,当然,只有主线程可以捕获这个信号,我的包中的代码根本无法捕获它。虽然它不能解决我的问题,但它可能是您的解决方案。

最后我发现Python中有一个内置的模块,名为subprocess。这意味着你可以用它运行一个子真实的完整进程,也就是说,这个进程有自己的主线程,所以你可以在这里轻松地用SIGNAL运行你的代码。虽然我不知道使用它的性能,但它对我来说效果很好。 PS,您可以在 Python 文档中找到有关 subprocess 的所有详细信息。

谢谢~

I use Python 3.5 and Django 1.8.5 with my project, and I met a similar problem recently. I can easily run my xxx.py code with SIGNAL directly, but it can't be executed on Django as a package just because of the error "signal only works in main thread".

Firstly, runserver with --noreload --nothreading is usable but it runs my multi-thread code too slow for me.

Secondly, I found that code in __init__.py of my package ran in the main thread. But, of course, only the main thread can catch this signal, my code in package can't catch it at all. It can't solve my problem, although, it may be a solution for you.

Finally, I found that there is a built-in module named subprocess in Python. It means you can run a sub real complete process with it, that is to say, this process has its own main thread, so you can run your code with SIGNAL easily here. Though I don't know the performance with using it, it works well for me. PS, you can find all details about subprocess in Python Documentation.

Thank you~

伊面 2024-12-29 13:30:41

有一种更干净的方法,不会破坏您使用线程和进程的能力。

将您的注册调用放入manage.py中:

def handleKill(signum, frame):
    print "Killing Thread."
    # Or whatever code you want here
    ForceTerminate.FORCE_TERMINATE = True 
    print threading.active_count()
    exit(0)


if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")

from django.core.management import execute_from_command_line

signal.signal(signal.SIGINT, handleKill)
signal.signal(signal.SIGTERM, handleKill)

execute_from_command_line(sys.argv)

There is a cleaner way, that doesn't break your ability to use threads and processes.

Put your registration calls in manage.py:

def handleKill(signum, frame):
    print "Killing Thread."
    # Or whatever code you want here
    ForceTerminate.FORCE_TERMINATE = True 
    print threading.active_count()
    exit(0)


if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")

from django.core.management import execute_from_command_line

signal.signal(signal.SIGINT, handleKill)
signal.signal(signal.SIGTERM, handleKill)

execute_from_command_line(sys.argv)
家住魔仙堡 2024-12-29 13:30:41

尽管问题没有准确描述您所处的情况,但这里有一些更通用的建议:

信号仅发送到主线程。因此,信号处理程序应该位于主线程中。
从那时起,信号触发的操作需要传达给其他线程。我通常使用事件来执行此操作。信号处理程序设置事件,其他线程将读取该事件,然后意识到操作 X 已被触发。显然,这意味着事件属性应该在线程之间共享。

Although the question does not describe exactly the situation you are in, here is some more generic advice:

The signal is only sent to the main thread. For this reason, the signal handler should be in the main thread.
From that point on, the action that the signal triggers, needs to be communicated to the other threads. I usually do this using Events. The signal handler sets the event, which the other threads will read, and then realize that action X has been triggered. Obviously this implies that the event attribute should be shared among the threads.

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