这个问题非常有线,让我发疯。任何帮助表示赞赏!
我们有一些底层C代码,它们将由Python模块调用(Python版本2.6,Django
框架,版本1.4)。我们通过SWIG
2.0.9构建了Python绑定。我们在python manage.py shell
提示中使用了它们。他们运作良好。
如果我们运行python manage.py runserver 0.0.0.0:8001
,一切都运行良好。但是当我们将应用程序部署为Apache虚拟主机时,Python绑定会突然失败(其他网页不使用C代码就可以了)。它的网址类似于http://hostname.com/basic 。这是我们的conf
文件:
#Listen 80
<VirtualHost *:80>
ServerName hostname.com/basic
ServerAdmin caisj@example.com
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
DocumentRoot /home/browser/BASIC/basic
Alias /static/admin /home/browser/BASIC/_py/lib/python2.6/site-packages/Django-1.4-py2.6.egg/django/contrib/admin/static/admin
Alias /static /home/browser/BASIC/basic/static
WSGIScriptAlias /basic /home/browser/BASIC/basic/basic.wsgi
ErrorLog /home/browser/BASIC/basic/log/basic.error.log
<Directory /home/browser/BASIC/basic>
<Files basic.wsgi>
Order deny,allow
Allow from all
</Files>
</Directory>
LogLevel info
CustomLog /home/browser/BASIC/basic/log/basic.access.log combined
我们需要两次查询C代码。第一个仍然有效并返回正确的结果。但第二次试验刚崩溃。代码停止,不返回任何内容。一些代码片段:
from some.basic import rmq # this is the Python binding created by SWIG
class Maxi:
@staticmethod
@contextmanager
def open(rmqfile):
driver = None
try:
driver = Maxi(rmqfile)
yield driver
finally:
if driver: driver.close()
def __init__(self, rmqfile):
with open(rmqfile) as f:
self.rmqfile = yaml.load(f)
self.handlers = dict()
# The rmq.i:
# int rmq_query (rmq_track t, unsigned int p, unsigned int q);
# rmq_track rmq_load (char filename[]);
def query(self, chrom, start, end):
h = rmq.rmq_load(self.rmqfile[chrom]))
rs = rmq.rmq_query(h, start-1, end-1) # It works and result is correct
rs = rmq.rmq_query(h, start-1+1, end-1+1) # !!! Crashes here !!!
return rs
def close(self):
for h in self.handlers.itervalues():
rmq.rmq_unload(h)
# ==== Django views code ====
driver = Maxi('yaml_config_file_to_load')
result.append(driver.query('chr1', 1, 100000)
我猜这是由一些文件权限问题引起的。但即使我将所有Python绑定文件设置为777,它仍然在作为Apache虚拟主机工作时失败。
我确实尝试删除了dirver.close()
语句,但仍然失败了。在代码跟踪之后,永远不会调用close()
方法。
也许有一些配置会导致python绑定的生命周期无法正常管理。但我无法确定原因。
请帮忙。非常感谢。
==================
更新
阅读http://code.google.com/p/modwsgi/wiki/ApplicationIssues#Python_Simplified_GIL_State_API后,我添加到我的conf
文件中:
WSGISocketPrefix /var/run/wsgi
WSGIApplicationGroup %{GLOBAL}
WSGIPythonHome /home/browser/BASIC/_py
<VirtualHost *:80>
......
WSGIApplicationGroup %{GLOBAL}
WSGIDaemonProcess hostname.com/basic processes=2 threads=15 display-name=%{GROUP}
WSGIProcessGroup hostname.com/basic
......
</VirtualHost>
但它报告错误:
Premature end of script headers: basic.wsgi
答案 0 :(得分:1)
此处记录了SWIG问题的解决方案:
另请确保阅读:
答案 1 :(得分:0)
最后!经过大量搜索并尝试了很多,我解决了这个问题。这是我的conf
文件:
# Important! My http.conf does not contain this line. So Apache seems to
# load the mod_wsgi.so from somewhere else, which is unluckily not compatible
# with my C codes.
LoadModule wsgi_module modules/mod_wsgi.so
# Place to store file for socket communications. I created the folder manually.
WSGISocketPrefix /var/run/wsgi
<VirtualHost *:80>
......
# My wsgi configuration file
WSGIScriptAlias /basic /home/browser/BASIC/basic/basic.wsgi
# Make the virtual host using only one Python sub interpreter.
WSGIApplicationGroup %{GLOBAL}
# Make it run under the daemon mode
WSGIDaemonProcess hostname.com/basic processes=1 threads=15 display-name=%{GROUP} \
python-path=/home/browser/BASIC/_py/lib/python2.6/site-packages
WSGIProcessGroup hostname.com/basic
......
</VirtualHost>