【问题标题】:Unable to stop python callbacks from a python C extension无法从 python C 扩展停止 python 回调
【发布时间】:2012-07-17 13:38:03
【问题描述】:

我正在尝试将 C++ 相机帧采集库包装到 Python 中。我的回调函数有问题。我使用以下代码从 C 函数调用 python 函数:

PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
result = PyObject_CallObject(my_callback, arglist);
if(result == NULL){
    caller.stopLive();
}
Py_DECREF(result);
Py_DECREF(arglist);
PyGILState_Release(gstate);

回调工作正常。当我尝试使用相机库函数停止回调时,就会出现问题。如果python回调函数较短,相机库函数可以停止回调,但如果python回调函数较长,则相机库函数无法停止回调,程序冻结。

有人遇到过类似的问题吗?您对尝试什么有什么建议吗?

编辑: 停止回调的代码是:

static PyObject * stopcallback(PyObject *self, PyObject *args)
{
    if(grabber->isListenerRegistered(pListener)){
        grabber->removeListener(pListener);
        while(grabber->isListenerRegistered(pListener)){
            Sleep(0);
        }
        delete pListener;
        printf("Callback stopped\n");
        Py_RETURN_NONE;
    }
}

我从 Python 调用这个函数。

【问题讨论】:

  • 不清楚您所说的“停止回调”是什么意思?你能分享你用来尝试这个的代码吗?请注意,您已将 GIL 锁定在此处(您应该这样做)。 “停止回调”是否涉及运行 Python 代码?如果是这样,它将被 GIL 阻止。

标签: c++ python c callback


【解决方案1】:

你说“如果 python 回调函数很短,相机库函数能够停止回调”。

我想知道库在运行(或挂起?)时是否无法删除回调。

如果回调很短,则有一段时间没有运行(或未挂起),因此库可以将其删除,但如果回调很长,则正在运行(或挂起)几乎所有时间,所以图书馆没有机会删除它。

【讨论】:

  • 我认为你是对的。那么问题是,如何允许库删除回调。我猜 GIL 锁必须以某种方式从 C 代码中破解?有没有办法做到这一点?
  • 能否修改回调函数使其短路?例如,以if stopping: return 开头并在您即将删除回调时执行stopping = True
  • 我想我可以这样做,虽然它看起来有点 hack。我会告诉你进展如何。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多