Cython 回调导致内存损坏/段错误

发布于 2024-11-09 10:36:01 字数 956 浏览 0 评论 0原文

我正在使用 cython 将 python 与 c++ 库连接起来。我需要一个 C++ 代码可以调用的回调函数。我还需要将对特定 python 对象的引用传递给此函数。从回调演示中可以清楚地看出这一点。

但是,当从 c++ 线程(pthread)调用回调时,我会遇到各种错误:

  1. 将函数指针和类/对象(作为 void*)传递给 c++
  2. 将指针存储在 c++ 中
  3. 启动运行循环的新线程(pthread)
    1. 使用存储的函数指针调用函数并传回类指针(void*)
  4. 在 python 中:将 void* 转换回类/对象
  5. 调用上述类/对象的方法 (错误)

步骤 2 和 3 在 c++ 中。

这些错误主要是分段错误,但有时我会抱怨一些低级别的 python 调用。

我有完全相同的代码,在 python 中创建一个线程并直接调用回调。这工作正常。所以回调本身正在工作。

我确实需要一个在 C++ 中运行的单独线程,因为该线程正在与硬件通信,并且有时会调用我的回调。

我还对所有正在传递的指针进行了三次检查。它们指向有效的位置。

我怀疑从 C++ 线程使用 cython 类时存在一些问题..?

我在 Ubuntu 上使用 Python 2.6.6。

所以我的问题是: 我可以从非 python 线程操作 python 对象吗? 如果没有,有没有办法让线程兼容Python? (pthread)

这是从 C++ 线程调用时已经导致问题的最小回调:

cdef int CheckCollision(float* Angles, void* user_data):
    self = <CollisionDetector>user_data
    return self.__sizeof__() # <====== Error

I am interfacing python with a c++ library using cython. I need a callback function that the c++ code can call. I also need to pass a reference to a specific python object to this function. This is all quite clear from the callback demo.

However I get various errors when the callback is called from c++ thread (pthread):

  1. Pass function pointer and class/object (as void*) to c++
  2. Store the pointers within c++
  3. Start new thread (pthread) running a loop
    1. Call function using the stored function pointer and pass back the class pointer (void*)
  4. In python: cast void* back to class/object
  5. Call a method of above class/object (Error)

Steps 2 and 3 are in c++.

The errors are mostly segmentation faults but sometimes I get complaints about some low level python calls.

I have the exact same code where I create a thread in python and call the callback directly. This works OK. So the callback itself is working.

I do need a separate thread running in c++ since this thread is communicating with hardware and on occasion calling my callback.

I have also triple-checked all the pointers that are being passed around. They point to valid locations.

I suspect there are some problems when using cython classes from a c++ thread..?

I am using Python 2.6.6 on Ubuntu.

So my question is:
Can I manipulate python objects from a non-python thread?
If not, is there a way can make the thread python-compatible? (pthread)

This is the minimal callback that already causes problems when called from c++ thread:

cdef int CheckCollision(float* Angles, void* user_data):
    self = <CollisionDetector>user_data
    return self.__sizeof__() # <====== Error

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

·深蓝 2024-11-16 10:36:01
  1. 不,在没有首先获取 GIL 的情况下,您不能操作 Python 对象。您必须使用 PyGILState_Ensure() + PyGILState_Release() (请参阅 PyGILState_Ensure 文档)

  2. 如果你明确地获取引用,并在以下情况下释放它,你可以确保你的对象不会被 python 删除:您不再将其与 Py_INCREF()Py_DECREF() 一起使用。如果你将回调传递给你的c++,并且你不再有引用,也许你的python对象被释放,并且崩溃发生(参见Py_INCREF 文档)。

免责声明:我并不是说这是您的问题,只是为您提供追踪错误的提示:)

  1. No, you must not manipulate Python objects without acquiring GIL in the first place. You must use PyGILState_Ensure() + PyGILState_Release() (see the PyGILState_Ensure documentation)

  2. You can ensure that your object will be not deleted by python if you explicitly take the reference, and release it when you're not using it anymore with Py_INCREF() and Py_DECREF(). If you pass the callback to your c++, and if you don't have a reference taken anymore, maybe your python object is freed, and the crash happen (see the Py_INCREF documentatation).

Disclamer: i'm not saying this is your issue, just giving you tips to track down the bug :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文