IPython noteb中多线程扩展的实时输出

2024-10-01 00:26:07 发布

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

我有一个c++函数,它生成一个子线程来提供异步输出(最终这将用于实现一个进度监视器,报告多线程算法的状态)。我希望子线程能够输出到任何地方,包括IPython笔记本。为此,我为子线程提供了一个接受字符串的回调例程。如果我想输出到Python stdout,我用一个指向公开的cython例程的指针初始化这个回调(使用api关键字)。在

我花了一些时间来正确实现所有GIL簿记,这将允许我从子线程执行Python代码,但最终我让代码在经典的Python提示符下工作。工作意味着每隔半秒(或多或少)我都会在Python提示符上从子线程获得更新的输出。在

问题是,当我从IPython qtconsole或IPython笔记本执行这些代码时,直到函数返回,输出才会出现。此时,所有输出都会同时出现(这对于进度监视器来说显然是不可接受的)。在

我怀疑这与GIL如何从Python内核传递到IPython内核端客户端有关?如何允许内核端IPython客户端向笔记本发送新的输出?在

pymontor.hpp的内容

#include "Python.h"
#include "compel_api.h"

void printSomeOutput(PyObject *callable);
void printSomeOutputMT(PyObject *callable);

pymonitor.cpp的内容

^{pr2}$

compel.pdx的含量:

cdef extern from "pymonitor.hpp" namespace "compel":
    cdef void printSomeOutputMT(object callable)

compel.pyx的内容:

cdef public api cy_print_message(string message, object callback):
    callback(message)

def test_printMT(object callback):
    printSomeOutputMT(callback)

在Python/IPython notebook命令行进行测试:

from compel import *
def f(m):
    import sys
    print(m)
    sys.stdout.flush()
test_printMT(f)

Tags: 代码api内容messageobjectipythoncallback笔记本