0

我是 python 和 C 扩展的新手。我正在编写一个 python 代码,其中创建了两个线程并定义了一个回调函数 py_cb()。在一个线程中,我在特定时间间隔后附加到全局列表,而在另一个线程中,我正在调用 C 扩展库 api。C 扩展 api 生成一个线程,该线程调用在我的原始文件中定义的 python 回调函数 (py_cb)。在回调函数中,我试图显示全局列表,但它似乎有不同的 id。我使用 id(listName) 检查了它。有没有办法可以在 C 扩展 python 回调函数中使用正确的全局变量?我假设全局值将在所有线程之间共享,不是这样吗?另外,请提出更好的解决方案。

以下是C代码:

char *MODULE_NAME = "simple";
---

PyMODINIT_FUNC init_cmodule(void)
{
    PyObject *m = Py_InitModule3("_cmodule",module_methods,module_docstring);
    if (m == NULL)
    return;
}

static PyObject *cmodule_cmodule(PyObject *self, PyObject *args)
{
    int value = register_cb();
    PyObject *ret = Py_BuildValue("i",value);
    return ret;
}


void notifyFooHandle()
{
    printf("inside the notify_foo function\n");
    pModule = PyImport_ImportModule(MODULE_NAME);
    if (!pModule) {
        printf ("Failed to load the module\n");
        return;
    }
    PyObject *pFunc;
    pFunc = PyObject_GetAttrString(pModule, "py_cb");
    if (pFunc && PyCallable_Check(pFunc)) {
        PyObject_CallObject(pFunc,NULL);

    }
    else {
        Py_DECREF(pFunc);
        PyErr_Print();
        printf("Failed to send notification\n");
        return;
    }
    return;
}

void notify_foo(void)
{
    int t = 5;

    while (t < 10) {
        notifyFooHandle();
        sleep(5);
        t++;
    }
    return;
}

int register_cb(void)
{
    pthread_t notify_t;
    int rc = pthread_create(&notify_t, NULL, (void *) &notify_foo,NULL);
---
}

以下是 simple.py 文件中的 python 回调 API:

def py_cb():
    print "Received a call back from cmodule"
    global myList
    print "Global myList is ", id(myList)
    print myList
    return
4

1 回答 1

0

你能向我们展示你的 C 库中的代码吗?如果你在那里初始化一个 python VM,然后调用 py_cb,很容易理解为什么列表不同:你有两个不同的 python VM 实例。

编辑:

我认为你的问题是你使用了两个不同的 python 实例。首先,你的主程序是python。在那种情况下,您有一个全局“myList”,因此从那里调用的每个函数都将访问“myList”的特定实例。然后,加载一个 C 模块。当该 C 模块打开原始 python 模块以加载 py_cb 时,您正在使用不同的 python 实例,您将拥有第二个“myList”。简而言之,您有两个不同的 python 实例正在运行,一个是您在运行主要 python 脚本时创建的,另一个是您在 C 库中创建以调用 py_cb。

如果你想共享一个通用的 python 实例,你必须在 C 中创建你的实例,让它在你的 C 模块中全局可访问,在那里插入你的 C 函数,然后运行你的主要 python 函数。当 python 调用 C 函数时,您将在原始地址空间内,而不是新地址空间,并且当您回调 python 时,您将始终使用相同的 python 实例。

于 2014-08-26T10:01:55.713 回答