从C API

时间:2017-02-03 17:02:06

标签: c++ multithreading python-2.7 python-c-api

与讨论here的问题类似,我需要从多线程C ++程序中调用异步python代码。但它不会是调用python执行的主线程(调用Py_Initialize()PyEval_InitThreads()的主线程)。

我不知道如何管理对PyEval_SaveThread()PyEval_RestoreThread()的调用:调用PyEval_SaveThread()并将检索到的线程状态保持未使用是否安全?拨打PyThreadState_Clear()会有意义吗?

我想尽可能使用PyGILState_Ensure()PyGILState_Release()来管理GIL。

谢谢!

编辑1:

我在主线程中试过了:

PyEval_InitThreads();
Py_Initialize();

PyThreadState* _state = PyEval_SaveThread();
PyEval_AcquireLock();
PyThreadState_Clear(_state);
PyEval_ReleaseLock();

我遇到了分段错误。

编辑2:

我没有办法在PyThreadState之后放弃PyEval_SaveThread(),但我确认只能处理 保存线程后,PyGILState_Ensure()PyGILState_Release()保护python执行,无论我们是否仍在同一个线程中。

最后,似乎必须在完成之前恢复线程。

编辑3:

  • 今天,使用Python 2.7,在不久的将来转向Python 3.
  • 关于清除python线程状态时的分段错误,没有错误消息。在最终确定时出现seg故障。 Python可能猜测它必须关闭我刚刚清除的主线程?
  • 当程序终止时,如果没有发生错误,python执行结束,然后它应该能够很好地完成。当我不清除线程状态时,它就是它运行的方式。

1 个答案:

答案 0 :(得分:0)

我也在学习,所以这里的信息可能不完整,但至少我可以克服分段错误。

使用Python 2.7 C API。

在main()中:

No errors!

在你的主题的run方法中:

Py_Initialize();
PyEval_InitThreads();

// IMPORTNT: You must release before launching threads
PyEval_ReleaseLock();

// Create/Start threads here

// Wait until threads ends

// Before finishing, acquire the GIL
PyGILState_STATE gstate = PyGILState_Ensure();
Py_Finalize();

注意: 当我从我的线程调用的Python代码涉及导入模块和创建pyplot对象时,我遇到了一些麻烦,但这是另一个故事。