ValueError:信号仅在主线程中有效 - Django - mod_wsgi

9 投票
2 回答
6414 浏览
提问于 2025-04-21 08:04

我正在尝试用Python的signal模块来执行一个命令行指令,并且想要终止它。

我知道信号只在主线程中有效,所以我用以下命令启动了Django开发服务器:

python manage.py runserver --nothreading --noreload

这样运行是没问题的。

但是当我用Apache和mod_wsgi来部署Django应用时,出现了以下错误:

[Fri Sep 12 20:07:00 2014] [error]     response = function.call(request, **data)
[Fri Sep 12 20:07:00 2014] [error]   File "/Site/cloud/lib/python2.6/site-packages/dajaxice/core/Dajaxice.py", line 18, in call
[Fri Sep 12 20:07:00 2014] [error]     return self.function(*args, **kwargs)
[Fri Sep 12 20:07:00 2014] [error]   File "/Site/cloud/soc/website/ajax.py", line 83, in execute
[Fri Sep 12 20:07:00 2014] [error]     data = scilab_run(code, token, book_id, dependency_exists)
[Fri Sep 12 20:07:00 2014] [error]   File "/Site/cloud/soc/website/helpers.py", line 58, in scilab_run
[Fri Sep 12 20:07:00 2014] [error]     output = task.run().communicate()[0]
[Fri Sep 12 20:07:00 2014] [error]   File "/Site/cloud/soc/website/timeout.py", line 121, in run
[Fri Sep 12 20:07:00 2014] [error]     lambda sig,frame : os.killpg(self.pgid,self.timeoutSignal) )
[Fri Sep 12 20:07:00 2014] [error] ValueError: signal only works in main thread

这是我的Apache虚拟主机设置:

WSGIDaemonProcess testcloud display-name=scilab_cloud  user=apache group=apache threads=1
WSGIProcessGroup testcloud
WSGIScriptAlias / /Site/cloud/soc/soc/wsgi.py
WSGIImportScript /Site/cloud/soc/soc/wsgi.py process-group=testcloud application-group=%{GLOBAL}

我在httpd.conf文件中还有以下设置,这些设置是在虚拟主机之外的:

WSGIRestrictSignal Off
WSGISocketPrefix /var/run/wsgi

这里是一个链接,里面有使用signal的程序,以及我在Django应用中使用的程序。

任何帮助都将不胜感激。

2 个回答

-1

我不太确定这个问题能不能那么简单解决,或者至少用mod_wsgi可能不行。选择是否使用线程,实际上是apache和mod_wsgi在构建和运行时的设置,这两个默认都是选择使用线程的。

我本来想给你推荐一些文档,但我只能发两个链接,所以我觉得不如把这两个链接用来提个解决方案更好:

我在用python运行shell命令时,使用sh的体验还不错,它甚至有一个异步执行的模块。也许你可以先让你的python代码运行这个shell命令,然后在需要的时候处理回调对象。

或者,更好的办法是,sh在处理信号时需要你小心,所以你可以不使用异步执行模块,而是在另一个进程中运行,使用multiprocessing.Process,这样你就能得到一个Process对象,随时可以用object.terminate()来终止它。

0

你在setting.py文件里开启了DEBUG模式吗?如果开启了,试着把它关掉,看看问题还会不会出现。

撰写回答