从mod_wsgi Django应用导入numpy时偶尔出现ctypes错误
这是一个设置情况:
- 在mod_wsgi上运行的Django(1.2)应用,使用了ctypes
- Python版本是2.6.5
- Apache版本是2.2.3
- SELinux已禁用
- 操作系统是64位的RedHat EL 5
- 部分文件系统是通过nfs挂载的
有时候,当我重启Apache时,会出现导入错误,特别是在它尝试导入ctypes的时候。每一个请求都会失败,显示500错误。如果我重启Apache,通常一切又会恢复正常。
这是错误的堆栈跟踪信息:
Traceback (most recent call last):
File "/home/appfirst/django/django/core/handlers/base.py", line 80, in get_response
response = middleware_method(request)
-------------- A BUNCH OF DJANGO MIDDLEWARE STUFF HERE -------------
File "/home/appfirst/django/django/utils/importlib.py", line 35, in import_module
__import__(name)
File "/home/appfirst/backend/backend/streamer/views.py", line 6, in <module>
import appfirst.main.models as FEmodels
File "/home/appfirst/frontend/appfirst/main/models.py", line 27, in <module>
import numpy, math, mpmath
File "/usr/lib64/python2.6/site-packages/numpy/__init__.py", line 43, in <module>
import ctypeslib
File "/usr/lib64/python2.6/site-packages/numpy/ctypeslib.py", line 9, in <module>
import ctypes
File "/usr/lib64/python2.6/ctypes/__init__.py", line 546, in <module>
CFUNCTYPE(c_int)(lambda: None)
MemoryError
我原以为这可能和一个bug有关,但我已经关闭了SELinux,我以为这样就不会出现这种情况:
有没有什么建议可以帮助我稳定地重现这个问题或者修复它?这让我很困惑!
3 个回答
考虑把SELinux关掉。这样应该能解决问题。
如果其他人遇到这个问题,我的解决办法是把Python从3.7升级到3.8。
出问题的那一行代码在这里:https://github.com/python/cpython/blob/3.7/Lib/ctypes/__init__.py#L273
在3.8版本中,这一行被删除了:https://github.com/python/cpython/blob/3.8/Lib/ctypes/__init__.py#L261-L270
希望这能帮到某些人,免去尝试修改ctype/__init__.py
的麻烦,因为我尝试过但没成功,主要是因为conda pack
处理标准Python库的方式。
希望这对你有帮助
我也遇到过这个问题。在我的情况下,它发生在我从一个在Apache下运行的PHP脚本中执行一个Python脚本时,这个系统是64位Linux。[被运行的Python代码是一个pypy沙箱的前端。] 同样的代码在32位系统上运行得很好,甚至在直接从命令行执行PHP脚本时也没问题。我的“解决办法”就是在ctypes/init.py文件中把那行“CFUNCTYPE(c_int)(lambda: None)”注释掉。这是文件的最后一行,前面还有一条评论,说明程序员也不太明白发生了什么!
# XXX for whatever reasons, creating the first instance of a callback
# function is needed for the unittests on Win64 to succeed. This MAY
# be a compiler bug, since the problem occurs only when _ctypes is
# compiled with the MS SDK compiler. Or an uninitialized variable?
CFUNCTYPE(c_int)(lambda: None)
显然,cpython内部还有更深层次的问题,但这个解决办法对我有效。