我想为C ++组件 invoker 创建一个Python绑定 函数对象,稍后从另一个线程调用 。 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
正在发生
调用正确但但是执行了callable本身的输出
很久以后(准确地说最多57秒)。
我现在有两个问题:
因为invoker
不立即运行可调用对象但存储它
一个队列,invoke()
在调用之前返回,Python应该清理
呼叫所需的所有数据。不是吗?
我应该复制或保护 callable和所有参数吗?
怎么办呢?
为什么Python代码的输出会在以后的C ++中打印出来
输出不是?由于C ++代码和Python代码运行相同
他们共享的流程stdout
。我可以通过电话解决这个问题
回调中sys.stdout.flush()
,但我不明白为什么。