我有一个嵌入式模块,类为:
PYBIND11_EMBEDDED_MODULE(appmodule, m) {
py::class_<Camera>(m, "Camera")
.def(py::init<>())
.def("onFrameEvent", &Camera::onFrameEvent, pybind11::call_guard<pybind11::gil_scoped_release>());
}
正如文档中所述,在使用多线程时,我添加了
pybind11::call_guard<pybind11::gil_scoped_release>()
.
接下来,我有一个继承QThread的类,它重载了
run()
方法:
class Worker : public QThread {
Q_OBJECT
public:
Worker(Camera* cam);
void run();
private:
Camera* camera;
};
void Worker::run() {
// Next code runs in other thread:
QTimer* loop = new QTimer();
connect(loop, &QTimer::timeout, [=]() {
cv::Mat m = camera->getOpenCVMat();
py::array_t<uint8_t> output(
py::buffer_info(
m.data,
sizeof(uint8_t),
py::format_descriptor<uint8_t>::format(),
3,
std::vector<size_t> {static_cast<unsigned long>(m.rows), static_cast<unsigned long>(m.cols), 3},
std::vector<size_t> { sizeof(uint8_t) * static_cast<unsigned long>(m.cols) * 3, sizeof(uint8_t) * 3, sizeof(uint8_t)}));
camera->getPythonHandle().attr("onFrameEvent")(output); // Call event on python side
});
loop->start(1000);
QThread::exec();
}
python方面:
import appmodule
import cv2
class MyCamera(appmodule.Camera):
def __init__(self):
super().__init__()
def onFrameEvent(self, image):
cv2.imshow('', image)
为了初始化解释器,我使用
py::initialize_interpreter();
在开始
main()
功能。
问题是应用程序崩溃,并显示以下消息:
pybind11::handle::inc_ref()正在被调用,而GIL是
未持有或无效。请看
https://pybind11.readthedocs.io/en/stable/advanced/misc.html#common-sources-of-global-interpreter-lock-errors
获取调试建议。
如果你确信你的电脑里没有bug
代码,您可以#定义PYBIND11_NO_ASSERT_GIL_HELD_INCREF_DEF
禁用此检查。在这种情况下,你必须确保这个#define是
始终用于链接到给定翻译单元的所有翻译单元
pybind11扩展,否则将出现ODR违规。失败
函数对象上触发了pybind11::handle::inc_ref()调用。
调用pybind11::handle::dec_ref()时,GIL为
未持有或无效。请看
https://pybind11.readthedocs.io/en/stable/advanced/misc.html#common-全局解释器锁错误的来源
获取调试建议。如果你确信你的电脑里没有bug
代码,您可以#定义PYBIND11_NO_ASSERT_GIL_HELD_INCREF_DEF
禁用此检查。在这种情况下,你必须确保这个#define是
始终用于链接到给定翻译单元的所有翻译单元
pybind11扩展,否则将出现ODR违规。失败
函数对象上触发了pybind11::handle::dec_ref()调用。
libc++abi:由于类型的未捕获异常而终止
std::runtime_error:pybind11::handle::dec_ref()PyGILState_Check()
失败。
尝试定义PYBIND11_NO_ASSERT_GIL_HELD_INCREF_DECREF时,崩溃不会消失,但消息中只显示以下内容:
libc++abi:由于std::runtime_error类型的未捕获异常而终止:pybind11::handle::dec_ref()PyGILState_Check()失败。
我还试图添加
py::gil_scoped_release release;
在开始
run()
方法,但它没有解决问题
系统:MacOS Ventura