Python 为什么从粘贴应用程序中创建neo4j.GraphDatabase会导致segfault?
下面的代码导致Java发生故障:Python 为什么从粘贴应用程序中创建neo4j.GraphDatabase会导致segfault?,python,paste,neo4j,webob,Python,Paste,Neo4j,Webob,下面的代码导致Java发生故障: import os.path import neo4j from paste import httpserver, fileapp import tempfile from webob.dec import wsgify from webob import Response, Request HOST = '127.0.0.1' PORT = 8080 class DebugApp(object): @wsgify def __call__(
import os.path
import neo4j
from paste import httpserver, fileapp
import tempfile
from webob.dec import wsgify
from webob import Response, Request
HOST = '127.0.0.1'
PORT = 8080
class DebugApp(object):
@wsgify
def __call__(self, req):
# db = neo4j.GraphDatabase(tempfile.mkdtemp())
db = neo4j.GraphDatabase(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data'))
return Response(body='it worked')
def main():
app = DebugApp()
httpserver.serve(app, host=HOST, port=PORT)
if __name__ == '__main__':
main()
>>> import webob
>>> import app
>>> debug_app = app.DebugApp()
>>> response = debug_app(webob.Request.blank('/'))
>>> response.body
'it worked'
要复制,首先将代码保存到一个文件(比如app.py),然后运行python app.py
。然后在浏览器中尝试;您应该看到Java崩溃处理程序
Java堆栈跟踪的顶部如下所示:
Stack: [0xb42e7000,0xb4ae8000], sp=0xb4ae44f0, free space=8181k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [_jpype.so+0x26497] JPJavaEnv::NewObjectA(_jclass*, _jmethodID*, jvalue*)+0x37
C [_jpype.so+0x3c0e8] JPMethodOverload::invokeConstructor(_jclass*, std::vector<HostRef*, std::allocator<HostRef*> >&)+0x178
C [_jpype.so+0x3a417] JPMethod::invokeConstructor(std::vector<HostRef*, std::allocator<HostRef*> >&)+0x47
C [_jpype.so+0x1beba] JPClass::newInstance(std::vector<HostRef*, std::allocator<HostRef*> >&)+0x2a
C [_jpype.so+0x67b9c] PyJPClass::newClassInstance(_object*, _object*)+0xfc
C [python+0x96822] PyEval_EvalFrameEx+0x4332
C [python+0x991e7] PyEval_EvalCodeEx+0x127
大概是因为我在那个例子中完全避免了粘贴。也许这与Paste使用线程阻碍neo4j有关?我在neo4j论坛上注意到了一个类似的问题:
…但这只发生在关机时。问题不在于粘贴本身,而在于使用JPype的neo4j Python绑定。粘贴创建线程来处理传入的请求;neo4j应该是线程安全的,但是JPype在文档()中附带了以下警告: “在大多数情况下,基于操作系统级线程(即posix线程)的python线程都可以正常工作。唯一要记住的是在线程体中调用jpype.attachThreadToJVM(),使JVM可以从该线程使用。对于不自己启动的线程,可以调用isThreadAttachedToJVM()进行检查。” 我找不到执行此操作的代码,但我认为neo4j绑定中的一些Java代码可能在导入时调用
attachThreadToJVM
。如果是这样,当一个请求通过粘贴传递给一个工作线程,然后该线程从neo4j获取数据时,它跨越了线程边界,JVM附件规则可能无法满足
通过仅在单个线程中运行import neo4j
,可以避免崩溃。在上面的例子中,这是threading.Thread
所针对的可调用对象
不幸的是,这意味着即使neo4j是线程安全的,但当从Python使用时,它也必须被限制为单个线程。但考虑到这一点,这并不令人失望
更新:维护人员响应(),调查问题,并检查修复。我不知道在哪个版本的neo4j中可以使用它,而且我再也找不到提交到他们的github repo(),因此这代表重新测试。您是否使用新的Python绑定,信息如下:?是的,这些是我正在使用的绑定。欢迎使用StackOverflow。您可以/应该将此答案标记为已接受,以便其他人知道有解决方案。