2017-02-03 79 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