Cのスレッドで実行される組み込みのPythonプログラムがあります。
Pythonインタープリターがスレッドコンテキストを切り替えるとき(制御を別のスレッドに譲る)、特定の必要な操作を実行できるように通知を受け取りたいです。
それPy_AddPendingCall
がまさに私が探しているもののようです。ただし、APIドキュメントはこの関数について非常に簡潔であり、どのようPy_AddPendingCall
に使用されるかについて混乱しています。ドキュメントを読んだことから、私の理解は次のとおりです。
- ワーカースレッドが
Py_AddPendingCall
ハンドラー関数を呼び出して割り当てます。 - Pythonインタープリターが実行されると、別のスレッドに制御を渡すたびにハンドラー関数が呼び出されます
- ハンドラー自体はメインインタープリタースレッドで実行され、GILが取得されます
たとえば、使用方法を示すコードをグーグルでPy_AddPendingCall
検索しましたが、何も見つかりません。私自身がそれを使おうとすると、うまくいきません。ハンドラーが呼び出されることはありません。
私のワーカースレッドコード:
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
const char* PYTHON_CODE =
"while True:\n"
" for i in range(0,10): print(i)\n"
"\n";
int handler(void* arg)
{
printf("Pending Call invoked!\n");
abort();
}
void* worker_thread(void*)
{
PyGILState_STATE state = PyGILState_Ensure();
int res = Py_AddPendingCall(&func, nullptr);
cout << "Result: " << res << endl;
PyRun_SimpleString(CODE);
PyGILState_Release(state);
return 0;
}
int main()
{
Py_Initialize();
PyEval_InitThreads();
PyEval_ReleaseLock();
pthread_t threads[4];
for (int i = 0; i < 4; ++i)
pthread_create(&threads[i], 0, worker_thread, 0);
for (int i = 0; i < 4; ++i) pthread_join(threads[i], 0);
Py_Finalize();
}
この例でworker_thread
は、Cでpthreadワーカースレッドとして呼び出されます。このテストでは、4つのワーカースレッドを実行しているため、コンテキストの切り替えが発生するはずです。これは無限にループしますが、保留中の呼び出しハンドラーが呼び出されることはありません。
それで、誰かがどのように使用されることになっているのかを示す最小限の実用的な例を提供できますPy_AddPendingCall
か?