问题描述
我有一个要放入静态库的函数:
run_me.h
:
void run_me();
run_me.cpp
:
namespace {
std::mutex python_mutex;
struct PythonScopedLock {
PythonScopedLock() : _lock(python_mutex) {
PyEval_AcquireLock();
}
~PythonScopedLock() {
PyEval_ReleaseLock();
}
private:
std::lock_guard<decltype(python_mutex)> _lock;
};
struct PythonInterpreter {
PythonInterpreter() {
Py_InitializeEx(0);
PyEval_InitThreads();
PyEval_ReleaseLock();
}
~PythonInterpreter() {
PyEval_AcquireLock();
Py_Finalize();
}
};
const PythonInterpreter python_interpreter;
} //namespace
void run_me()
{
PythonScopedLock lock;
// import python module and call some python code
}
接下来,在以下可执行文件中,我几乎立即在PyObject_Malloc
上崩溃。
#include <tbb/tbb.h>
#include "run_me.h"
int main(){
using namespace tbb;
parallel_for(blocked_range<size_t>(0,1234,1),[&](const blocked_range<size_t>& r) {
for (auto it = r.begin(); it != r.end(); ++it) {
run_me();
}
});
}
我用gdb检查了线程,它们很好地等待着锁被解锁,但是其中之一崩溃了:
1 Thread 0x7ffff7fdb900 (LWP 21474) "tests" 0x00007ffff69374ed in __lll_lock_wait () from /lib64/libpthread.so.0
2 Thread 0x7fffef349700 (LWP 21483) "tests" 0x00007ffff69374ed in __lll_lock_wait () from /lib64/libpthread.so.0
3 Thread 0x7fffeef48700 (LWP 21484) "tests" 0x00007ffff69374ed in __lll_lock_wait () from /lib64/libpthread.so.0
* 4 Thread 0x7fffeeb47700 (LWP 21485) "tests" PyObject_Malloc (nbytes=41) at Objects/obmalloc.c:831
5 Thread 0x7fffee746700 (LWP 21486) "tests" 0x00007ffff69374ed in __lll_lock_wait () from /lib64/libpthread.so.0
6 Thread 0x7fffedf44700 (LWP 21488) "tests" 0x00007ffff69374ed in __lll_lock_wait () from /lib64/libpthread.so.0
7 Thread 0x7fffee345700 (LWP 21487) "tests" 0x00007ffff69374ed in __lll_lock_wait () from /lib64/libpthread.so.0
当我从PythonScopedLock
的主体中移出run_me
并将其放入lambda主体时,情况发生了变化。这样就可以了:
#include <tbb/tbb.h>
#include "run_me.h"
namespace {
std::mutex python_mutex;
struct PythonScopedLock {
PythonScopedLock() : _lock(python_mutex) {
PyEval_AcquireLock();
}
~PythonScopedLock() {
PyEval_ReleaseLock();
}
private:
std::lock_guard<decltype(python_mutex)> _lock;
};
} // namespace
int main(){
using namespace tbb;
parallel_for(blocked_range<size_t>(0,[&](const blocked_range<size_t>& r) {
for (auto it = r.begin(); it != r.end(); ++it) {
PythonScopedLock lock;
run_me();
}
});
}
我有几个问题:
-
在这种情况下,在lambda内或函数主体之间加锁有什么区别?对我来说是一样的,我只想将该锁隐藏在函数主体内。 -
崩溃的可能原因是什么? - 通过静态
const PythonInterpreter python_interpreter;
通过匿名命名空间中的变量进行解释程序初始化期间,除了静态初始化失败之外,还有哪些其他问题?
编辑
经过一番调试,我注意到lock
在run_me
定义的内部时,在静态库中,PyGILState_GetThisThreadState
返回NULL
。当lock
在外部时,则在主线程中返回与_PyThreadState_Current
相同的指针。这类问题的答案是数字1和2.。
问题3仍未解决。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)