gpt4 book ai didi

c++ - boost.python 不支持并行性?

转载 作者:可可西里 更新时间:2023-11-01 16:29:58 25 4
gpt4 key购买 nike

我正在尝试使用 boost.python 将一段 C++ 代码包装到 python 库中,但是,我发现多个实例不能同时运行:

代码(C++):

class Foo{
public:
Foo(){}
void run(){
int seconds = 2;
clock_t endwait;
endwait = clock () + seconds * CLOCKS_PER_SEC ;
while (clock() < endwait) {}
}

};

BOOST_PYTHON_MODULE(run_test)
{
using namespace boost::python;

class_<Foo>("test", init<>())
.def("run", &Foo::run)
;

}

使用 CMake (CMake) 编译:

add_library(run_test SHARED run_test.cpp)
target_link_libraries(run_test boost_python python2.7)

并使用以下代码(Python)进行了测试:

class Dos(threading.Thread):
def run(self):
printl('performing DoS attack')

proc = test()
proc.run()

for i in range(5):
t = Dos()
t.start()

输出表明代码以一种非常奇怪的方式并行化。每个线程应该只需要 2 秒,并且 4 个线程应该在我的四核机器上同时运行:

[2011-11-04 13:57:01] performing DoS attack
[2011-11-04 13:57:01] performing DoS attack
[2011-11-04 13:57:05] performing DoS attack
[2011-11-04 13:57:05] performing DoS attack
[2011-11-04 13:57:09] performing DoS attack

谢谢你的帮助!

最佳答案

您遇到的是 python 全局解释器锁。 GIL 一次只允许一个线程在 python 解释器中运行。

Boost.Python 的优势之一是您可以释放 GIL,执行 C++ 操作,然后在完成后收回。然而,这也是一种责任。 Python 通常会定期释放 GIL,让其他线程有机会运行。如果您使用 C++,这就是您的工作。如果你在拿着 GIL 的同时处理数字 2 小时,你会卡住整个解释器。

这可以很容易地通过一点反向 RAII 来修复:

class releaseGIL{
public:
inline releaseGIL(){
save_state = PyEval_SaveThread();
}

inline ~releaseGIL(){
PyEval_RestoreThread(save_state);
}
private:
PyThreadState *save_state;
};

现在您可以像这样更改您的代码:

class Foo{
public:
Foo(){}
void run(){
{
releaseGIL unlock = releaseGIL();
int seconds = 2;
clock_t endwait;
endwait = clock () + seconds * CLOCKS_PER_SEC ;
while (clock() < endwait) {}
}
}
};

请务必注意,在未持有 GIL 的情况下,您不得触摸任何 Python 代码或 Python 数据或调用解释器。这将导致您的解释器崩溃。

也可以走另一条路。当前不持有 GIL 的线程可以获取它,并调用 python。这可以是较早发布 GIL 的线程,也可以是从 c++ 开始但从未有过 GIL 的线程。这是 RAII 类:

class AcquireGIL 
{
public:
inline AcquireGIL(){
state = PyGILState_Ensure();
}

inline ~AcquireGIL(){
PyGILState_Release(state);
}
private:
PyGILState_STATE state;
};

用法留给学生作为练习。

附加说明(我总是忘了提这个):

如果您打算在 C++ 中使用 GIL,您的模块定义需要从以下代码开始:

BOOST_PYTHON_MODULE(ModuleName)
{
PyEval_InitThreads();

...
}

关于c++ - boost.python 不支持并行性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8009613/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com