【发布时间】:2011-05-08 09:03:42
【问题描述】:
下面是在多线程程序中使用 Python 解释器的例子:
#include <python.h>
#include <boost/thread.hpp>
void f(const char* code)
{
static volatile auto counter = 0;
for(; counter < 20; ++counter)
{
auto state = PyGILState_Ensure();
PyRun_SimpleString(code);
PyGILState_Release(state);
boost::this_thread::yield();
}
}
int main()
{
PyEval_InitThreads();
Py_Initialize();
PyRun_SimpleString("x = 0\n");
auto mainstate = PyEval_SaveThread();
auto thread1 = boost::thread(f, "print('thread #1, x =', x)\nx += 1\n");
auto thread2 = boost::thread(f, "print('thread #2, x =', x)\nx += 1\n");
thread1.join();
thread2.join();
PyEval_RestoreThread(mainstate);
Py_Finalize();
}
看起来不错,但不同步。 Python 解释器在 PyRun_SimpleString 期间多次释放和重新获取 GIL(参见 docs, p.#2)。
我们可以使用自己的同步对象序列化 PyRun_SimpleString 调用,但这是错误的方式。
Python 有自己的同步模块 - _thread 和 threading。但它们在这段代码中不起作用:
Py_Initialize();
PyRun_SimpleString(R"(
import _thread
sync = _thread.allocate_lock()
x = 0
)");
auto mainstate = PyEval_SaveThread();
auto thread1 = boost::thread(f, R"(
with sync:
print('thread #1, x =', x)
x += 1
)");
- 它会产生错误
File "<string>", line 3, in <module> NameError: name '_[1]' is not defined和死锁。
如何同步嵌入的python代码最高效?
【问题讨论】:
-
你期望什么输出?
-
@Sven Marnach :感谢您的评论,更新了问题。
标签: c++ python c multithreading