简体   繁体   English

如何从外语线程调用python函数(C ++)

[英]How to call a python function from a foreign language thread (C++)

I am developing a program that use DirectShow to grab audio data from media files. 我正在开发一个程序,使用DirectShow从媒体文件中获取音频数据。 DirectShow use thread to pass audio data to the callback function in my program, and I let that callback function call another function in Python. DirectShow使用线程将音频数据传递给我的程序中的回调函数,我让该回调函数调用Python中的另一个函数。

I use Boost.Python to wrapper my library, the callback function : 我使用Boost.Python包装我的库,回调函数:

class PythonCallback {
private:
    object m_Function;
public:
    PythonCallback(object obj)
        : m_Function(obj)
    {}

    void operator() (double time, const AudioData &data) {
        // Call the callback function in python
        m_Function(time, data);
    }

};

Here comes the problem, a thread of DirectShow calls my PythonCallback, namely, call the function in Python. 问题来了,DirectShow的一个线程调用我的PythonCallback,即在Python中调用该函数。 Once it calls, my program just crash. 一旦调用,我的程序就崩溃了。 I found this should be threading problem. 我发现这应该是线程问题。 Then I found this document: 然后我找到了这个文件:

http://docs.python.org/c-api/init.html http://docs.python.org/c-api/init.html

It seems that my program can't call to Python's function from thread directly, because there is Global Interpreter Lock. 似乎我的程序不能直接从线程调用Python的函数,因为有Global Interpreter Lock。 The python's GIL is so complex, I have no idea how it works. python的GIL非常复杂,我不知道它是如何工作的。 I'm sorry, what I can do is to ask. 对不起,我能做的就是问。 My question is. 我的问题是。 What should I do before and after I call a Python function from threads? 在从线程调用Python函数之前和之后我应该怎么做?

It may looks like this. 它可能看起来像这样。

void operator() (double time, const AudioData &data) {
    // acquire lock
    m_Function(time, data);
    // release lock
}

Thanks. 谢谢。 Victor Lin. 林维克。

Take a look at PyGILState_Ensure()/PyGILState_Release(), from PEP 311 http://www.python.org/dev/peps/pep-0311/ 从PEP 311 http://www.python.org/dev/peps/pep-0311/查看PyGILState_Ensure()/ PyGILState_Release()

Here is an example taken from the PEP itself: 以下是PEP本身的一个例子:

void SomeCFunction(void)
{
    /* ensure we hold the lock */
    PyGILState_STATE state = PyGILState_Ensure();
    /* Use the Python API */
    ...
    /* Restore the state of Python */
    PyGILState_Release(state);
}

Have the c++ callback place the data in a queue. 让c ++回调将数据放入队列中。 Have the python code poll the queue to extract the data. 让python代码轮询队列以提取数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM