以下是在多線程程序使用Python解釋的例子:在同步多線程程序嵌入式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代碼最有效的方式?
你會期望什麼輸出? – 2010-11-11 10:04:20
@Sven Marnach:謝謝你的評論,更新了這個問題。 – Abyx 2010-11-11 19:59:33