Python:安全地存储一个Python可调用函数及其参数来调用i

2024-05-29 09:48:19 发布

您现在位置:Python中文网/ 问答频道 /正文

< P>我想为C++组件创建Python绑定<强>调用器< /St> 函数对象,然后从另一个线程调用它。 在C++中的用法是这样的:

invoker my_invoker(thread_holding_context);

// this will queue ome_class::some_method() to be executed later in another
// thread and it returns immediately
my_invoker.invoke(std::bind(&some_class::some_method, this));
当然,你可以使用纯Python代码来代替C++。 组件,但是这个invoker是框架的一部分,框架在更大的范围内使用 上下文和我使用它。你知道吗

在Boost::Python中,包装器可以如下所示:

struct invoker_wrap 
    : public invoker, public wrapper<invoker> {
    explicit invoker_wrap(thread_holding_context) {...}

    void wrap_invoke(boost::python::object callable) {
        // queue the callable - don't execute it yet
        invoker::invoke(std::bind(&invoker_wrap::call, this, callable));
    }

    void call(boost::python::object callable) {
        std::cout << "call: " << callable.ptr() << std::endl;
        PyGILState_STATE gstate = PyGILState_Ensure();  // seems to be not needed
        callable();
        PyGILState_Release(gstate);                     // seems to be not needed
    }
};

class_<invoker_wrap, boost::noncopyable>("invoker", init<thread_holding_context &>())
    .def("invoke", &invoker_wrap::wrap_invoke);

Python代码类似于:

_invoker = invoker(thread_holding_context)

def my_func():
    print("%.1f %s: my_func()" % (time.time(), threading.currentThread().getName()))

def thread_func():
    while True:
        _invoker.invoke(my_func)
        time.sleep(1)

threading.Thread(target=thread_func).start()

这个代码在某种程度上是有效的,但是它的行为很奇怪。invoker::call正在 调用正确,但执行可调用本身的输出 过了很久(精确到57秒)。你知道吗

我现在有两个问题:

  • 因为invoker不会立即运行callable,而是存储它 一个队列invoke()在调用和Python应该清理之前返回 通话所需的所有数据。不是吗? 我应该复制还是保护可调用的和它的所有参数? 如何做到这一点?

  • > P>为什么在C++的时候打印Python代码的输出? 输出不是?因为C++代码和Python代码运行在同一个 它们共享的进程stdout。我可以打电话解决这个问题 sys.stdout.flush()但我不明白为什么。


Tags: 代码mycontextsomecallthisthreadclass

热门问题