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

时间:2011-05-25 19:04:06

标签: callback pthreads segmentation-fault cython

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

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

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

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

    我有完全相同的代码,我在python中创建一个线程并直接调用回调。这很好用。所以回调本身就有用了。

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

    我还对所有传递的指针进行了三重检查。他们指向有效的位置。

    我怀疑从c ++线程使用cython类时有一些问题..?

    我在Ubuntu上使用Python 2.6.6。

    所以我的问题是: 我可以从非python线程操纵python对象吗? 如果没有,有没有办法可以使线程python兼容? (并行线程)

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

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

1 个答案:

答案 0 :(得分:1)

  1. 不,您不能在不首先获取GIL的情况下操纵Python对象。您必须使用PyGILState_Ensure() + PyGILState_Release()(请参阅PyGILState_Ensure documentation

  2. 如果您明确地使用了引用,则可以确保python不会删除您的对象,并且当您不再使用Py_INCREF()Py_DECREF()时将其释放。如果你把回调传递给你的c ++,如果你没有引用它,可能你的python对象被释放,崩溃发生(参见Py_INCREF documentatation)。

  3. 发言人:我不是说这是你的问题,只是给你一些追踪错误的提示:)