【问题标题】:Cython callback causing memory corruption/segfaultsCython 回调导致内存损坏/段错误
【发布时间】:2011-05-25 19:04:06
【问题描述】:

我正在使用 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

【问题讨论】:

    标签: callback pthreads segmentation-fault cython


    【解决方案1】:
    1. 不,您必须首先获得 GIL 才能操作 Python 对象。你必须使用PyGILState_Ensure() + PyGILState_Release()(见PyGILState_Ensure documentation

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

    免责声明:我不是说这是你的问题,只是给你提示以追踪错误:)

    【讨论】:

      猜你喜欢
      • 2015-02-09
      • 1970-01-01
      • 2018-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多