2012-10-02 80 views
1

我开发了一个带多线程的boost.python C/C++程序。从线程提升python /导入模块需要ReleaseLock()。为什么?

main(),我创建一个线程:

PyEval_InitThreads();

pthread_create(& id,& detached_attr,newThread,NULL);

·在newThread()中,我调用了两个Py_ *函数。

Py_Initialize();

PyGILState_STATE gstate = PyGILState_Ensure();

然后,我打电话叫hoge() C++函数中newThread()

void hoge(){ 
    py::object main_module; 
    py::object main_namespace; 

    try { 
     main_module = py::import("__main__"); //segmentation fault 
     main_namespace = main_module.attr("__dict__"); 
    } catch (py::error_already_set const &) { 
     PyErr_Print(); 
    } 

    //Some boost python code 
} 

GDB回溯输出是在这里。

(gdb) bt 
#0 0x4032fe24 in __ctype_b_loc() from /lib/libc.so.6 
#1 0x4032fde8 in __ctype_b_loc() from /lib/libc.so.6 

为什么import()失败?我不知道。请告诉我如何解决这个问题。



--edit 28年12月12日---

我使用下面的方法解决了这个问题。

main(),我执行

Py_Initialize(); 
PyEval_InitThreads(); 
PyEval_ReleaseLock(); 

然后,我创建了新的线程。在新的线程,我执行

PyGILState_STATE gstate = PyGILState_Ensure(); 
CALL SOME PYTHON CODE 
PyGILState_Release(gstate); 

但我不知道为什么现在的作品。有人能告诉我原因吗?

+1

我建议先尝试更简单的例子。例如,试着让没有线程的代码片段运行。一旦一切按预期工作(测试!),然后尝试多线程。 –

+0

谢谢你的建议。 我可以解决这个问题。 – fantajista

+0

你是如何解决你的问题的?我有同样的问题.. –

回答

0

与许多其他解释型语言一样,Python通过使用全局解释器锁(或GIL)实现线程安全性(see this wiki),该锁可阻止并行操作两个python解释器调用。所以,你发出的任何python调用应该首先请求锁,执行你的命令,然后释放锁。你必须遵守这个规则,否则你可能会让口译人员崩溃,就像你在你的例子中所做的那样。注意你的函数hoge()没有请求GIL,因此崩溃。现在,使用GIL请求(或“确保”)和释放函数调用来包装代码并不能解决所有问题 - 您仍然需要确保当您有2个线程时,两个都将有权访问GIL。如果你不会在主线程中释放GIL,那么你的第二个线程会被永远阻塞!你尝试过吗?如果没有,你可以做它看看会发生什么。

正确的解决方案 - 您自己找到的解决方案是在每个线程获取并释放GIL,并确保您不会卡在其中一个GIL线程中,而其他线程正在饿死。

相关问题