Cha*_*l72 5 c python cpython python-c-api python-3.x
我有一个嵌入式Python程序,它在C中的一个线程中运行.
当Python解释器切换线程上下文(让控制到另一个线程)时,我希望得到通知,以便我可以执行某些必要的操作.
这似乎Py_AddPendingCall正是我正在寻找的.但是,API文档在这个函数上非常简短,我对应该如何Py_AddPendingCall使用感到困惑.通过阅读文档,我的理解是:
Py_AddPendingCall并分配处理函数.我用Google搜索了一些显示如何使用的代码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();
}
Run Code Online (Sandbox Code Playgroud)
在此示例中,worker_thread在C中作为pthread工作线程调用.在这个测试中,我运行了4个工作线程,因此应该进行一些上下文切换.这无限循环,但永远不会调用挂起的调用处理程序.
那么,有人可以提供一个最小的工作示例,说明Py_AddPendingCall应该如何使用?
挂起调用仅在主线程上执行,主线程只能在执行Python代码时为挂起的调用提供服务.因此,主线程必须运行解释器循环才能为任何挂起的调用提供服务.来自Python/ceval.c:
Py_MakePendingCalls(void)
{
...
/* only service pending calls on main thread */
if (main_thread && PyThread_get_thread_ident() != main_thread)
return 0;
...
}
Run Code Online (Sandbox Code Playgroud)
在嵌入场景中,"主线程"是任何线程调用PyEval_InitThreads(请注意,它也是第一次从Python代码启动线程时自动调用).由于您的主线程位于其中pthread_join,因此它不执行Python代码,因此不会调度挂起的调用.
另请注意,处理程序仅在将控制权交给主线程时执行 - 如果控制从一个工作程序转到另一个工作程序,则处理程序不会运行.因此,Py_MakePendingCalls可能不适合用于此任务的接口.
| 归档时间: |
|
| 查看次数: |
1404 次 |
| 最近记录: |