【问题标题】:Threaded python and C binding synchronization线程化 python 和 C 绑定同步
【发布时间】:2013-01-30 15:16:43
【问题描述】:

我正在为我的一个实时 C 库实现 Python 绑定。我读过 Python 中的线程不是真正的线程,它们并没有真正并行运行(因为全局解释器锁)。不过,我必须考虑以下情况。

想象一下下面的 C 函数:

int stoppable_lock(mutex *m, bool *stop)
{
    while (!stop || !*stop)
        if (timed_lock(m, SOME_TIME) == SUCCESS)
            return SUCCESS;
    return DIDNT_LOCK;
}

这个函数等待一个互斥体,但是通过使用stop,可以取消。在最简单的情况下,能够优雅地停止使用它的线程,无论互斥锁的其他用户发生什么(例如,如果他们在持有锁时死亡)。

我的问题是弄清楚如何为这个函数编写一个 Python 包装器。通过解析参数(使用PyArg_ParseTuple),我可以检索互斥锁,没问题。但是,可以向函数seem to be 发送的东西的类型是字符串、数字和对象。前两个显然不能替换bool *,我怀疑为bool * 编写一个包装器是个好主意。

我的问题是,我怎样才能得到一个参数,它是对变量的引用(与其他 python 线程共享),而不仅仅是它的副本?

这是我缺少的部分的功能(用于mutex.stoppable_lock(stop) 之类的用法):

static PyObject *_stoppable_lock(_mutex *obj, PyObject *args)
{
    int ret;
    BOOL_STAR stop;
    if (!PyArg_ParseTuple(args, "?", &stop))
    {
        PyErr_SetString(PyExc_ValueError, "Usage: mutex.stoppable_lock(BOOL_STAR)");
        return NULL;
    }
    ret = stoppable_lock(obj->orig, stop);
    if (_set_exception(ret))
        return NULL;
    Py_RETURN_NONE;
}

我不知道BOOL_STAR"?" 应该是什么。

【问题讨论】:

  • 你应该看看 PyCObject。它是一个 python 对象,其中包含一个 C 指针
  • @sions,所以 python 程序员反过来必须使用该对象,而不是他的程序中的普通 bool 变量?
  • 我不得不指出,如果 C 代码不涉及 Python 状态,则它可以免于 GIL。您的互斥锁是可以释放 GIL 并并行运行的代码的完美示例。
  • @nneonneo,感谢您的澄清!

标签: python cpython python-bindings


【解决方案1】:

您需要为 bool 创建一个包装器类型,并为嵌入的值使用 Python mutator 函数。如果您想避免创建自己的类型,并且如果您相信 C _Bool 与 C++ bool 相同,那么您可以使用ctypes.c_bool。然后 Python 脚本可以做

   stop = ctypes.c_bool(False)
   stoppable_lock(mutex, ctypes.addressof(stop))

然后另一个线程可以执行stop.value = True。扩展模块会期望一个 long,然后将其转换为指针。如果您希望这种类型更安全,则需要为 bool 创建自己的包装器类型。

【讨论】:

  • 看起来很合理。我会试一试
【解决方案2】:

我的问题是,我怎样才能得到一个参数,它是对变量的引用(与其他 python 线程共享),而不仅仅是它的副本?

您可以将stop 包装在一个可变对象中,并传递对该对象的引用。

【讨论】:

    【解决方案3】:

    Python 线程是真正的线程(至少在 CPython 中对于大多数线程实现后端而言)。但你是对的,因为 GIL,Python 代码本身永远不会并行运行,尽管许多函数(尤其是 IO)都可以。

    关于您的主要问题:如果您想直接遵循 C 实现逻辑(对 bool 有 ref),NPE 已经说过:您可以将它包装在一个可变对象中,例如:

    class MutableBool:
        value = False
    

    否则,stoppable_lock 的整个代码也可以很容易地用 Python 重新实现,然后它可能会变得更直接。

    【讨论】:

      猜你喜欢
      • 2011-06-15
      • 1970-01-01
      • 2011-10-12
      • 1970-01-01
      • 2012-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多