1

我正在为我的一个实时 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)我可以检索互斥锁,没问题。但是,可以发送给函数的东西的类型似乎是字符串、数字和对象。前两个显然不能代替 a 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"?"应该是什么。

4

3 回答 3

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 创建自己的包装器类型。

于 2013-01-30T17:21:53.523 回答
0

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

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

class MutableBool:
    value = False

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

于 2013-10-15T16:00:45.313 回答
0

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

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

于 2013-01-30T16:39:04.610 回答