2017-02-03 141 views
0

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

我不知道如何管理对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:

我没有找到一个方法只是PyEval_SaveThread()后放弃PyThreadState,但我确认它可能只与 PyGILState_Ensure()PyGILState_Release()处理,以保护蟒蛇执行一旦线程被保存,无论我们是否仍在同一线程中。

最后,它似乎是必须在最终确定之前还原线程。

编辑3:

  • 今天,使用Python 2.7,移动到Python 3在不久的将来。
  • 关于清除python线程状态时的段错误,没有错误信息。完成时出现seg故障。 Python可能会猜测它必须关闭我刚刚清除的主线程?
  • 当程序终止时,如果没有错误发生,python执行结束,那么它应该能够很好地完成。这是它运行的方式,当我不清除线程状态。
+0

几个问题: 1.此版本的目标用途是什么? 2.是否有错误信息? 3.当程序终止时会发生什么?例如你想终止python吗? – sterin

+0

@ user99279,谢谢,我在问题中加入了信息... – Grumot

回答

0

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

使用Python 2.7 C API。

在main():

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(); 

在你线程的run方法:

PyGILState_STATE gstate = PyGILState_Ensure(); 

// Your Python work, i.e: 
PyRun_SimpleString("print('Hello from Thread')"); 

PyGILState_Release(gstate); 

注: 目前,我有一些麻烦,当我是从调用Python代码我的线程涉及导入模块和创建pyplot对象,但这是另一回事。

+0

谢谢,很好的解决方法,先直接释放锁定...我会很快测试它;听起来很有希望 – Grumot