C言語とPythonのスレッド混用について詳しく説明します。


問題
C、Pythonとスレッドを混合して使用するプログラムがあります。一部のスレッドはCで作成され、Python解釈器の制御範囲を超えています。また、いくつかのスレッドは、Python C APIにおける関数を使用している。
ソリューション
もしあなたがC、Pythonとスレッドを混合したいなら、正しい初期化とPythonのグローバル解釈ロック(GIL)の管理が必要です。このようにするには、下記のコードをCコードに入れて、スレッドが作成される前に呼び出されることを確認してください。

#include <Python.h>
 ...
 if (!PyEval_ThreadsInitialized()) {
  PyEval_InitThreads();
 }
 ...
PythonオブジェクトまたはPython C APIを呼び出す任意のCコードについては、最初にGILを正しく取得し、リリースしたことを確認します。これはPyGILState_Ensure() およびPyGILState_Release() を用いて行うことができ、以下のようにする。

...
/* Make sure we own the GIL */
PyGILState_STATE state = PyGILState_Ensure();

/* Use functions in the interpreter */
...
/* Restore previous GIL state and return */
PyGILState_Release(state);
...
PyGILState_Ensure() を呼び出すたびに、対応する呼び出しPyGILState_Release() が必要である。
討論する
CとPythonに関する高度なプログラムでは、多くのことを一緒にするのが一般的です。C、Python、Cスレッド、Pythonスレッド、Pythonスレッドの混合使用かもしれません。解释器が正しい初期化されていることを確認してください。また、解释器のCコードが正しいGIL管理を実行しているので、大丈夫です。
注意すべきは、PyGILState_Ensure() を呼び出しても、解釈器がすぐに奪われたり、中断されたりしないことである。他のコードが実行されている場合、この関数は中断され、その実行コードがGILを解放していることが分かります。内部では、トランシーバーは、周期的なスレッド切り替えを行いますので、他のスレッドが実行されている場合は、最終的にはディストリビュータが実行できます。
以上はCとPythonのスレッド混用の詳細を詳しく説明しました。CとPythonスレッド混用の詳細については他の関連記事に注目してください。