0

这个问题很连贯,让我发疯。任何帮助表示赞赏!

我们有一些底层 C 代码,它们将被 Python 模块调用(Python 2.6 版,Django框架,1.4 版)。我们已经通过SWIG2.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
4

2 回答 2

1

此处记录的 SWIG 问题的解决方案:

还要确保您阅读:

于 2013-04-21T22:32:39.993 回答
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>
于 2013-04-22T15:12:21.683 回答