停止、暂停和恢复python解释器

经过前面的一系列铺垫,现在要迎来我们的终极成果了——在运行我们自定义的函数过程中,如果要停止、暂停和再恢复python解释器,应该如何操作呢?

如果自定义函数中有耗时操作应该如何处理呢?

如何通过python c api实现钩子的功能呢?

先上码:

 

int PythonRunner::tracer(PyObject *, _frame *, int, PyObject *)

{

    //Pause is requested...

    if (_instance->pauseRequested())

    {

        Py_BEGIN_ALLOW_THREADS;

        //If we are paused and no resume has been requested sleep

        while (!_instance->resumeRequested())

        {

            QThread::msleep(500);

        }

        Py_END_ALLOW_THREADS;

    }

    //Abort requested

    else if (true == _instance->interruptRequested())

    {

        Py_AddPendingCall(&PythonRunner::raiseException, NULL);

    }

 

    // Otherwise proceed normally.

    return 0;

}

 

int PythonRunner::raiseException(void *)

{

//    PyErr_SetInterrupt();

    PyErr_SetString(PyExc_KeyboardInterrupt, "Abort");

    return -1;

}

 

void PythonRunner::run()

{

    PyEval_SetTrace(PythonRunner::tracer, NULL);

 

    runPython();

}

   

 static int tracer(PyObject *, struct _frame *, int, PyObject *);

 static int raiseException(void *);

 

 

由于整个工程的代码贴上去会比较乱,只把主要的部分说下。

static int tracer(PyObject *, struct _frame *, int, PyObject *)该函数被用于注册回调, 用它可以实现钩子的功能。啥是钩子?简单来说就是执行每行代码前都会进入这个回调函数。注意struct _frame该结构体,需要包含#include <python3.5/frameobject.h>这个头文件,否则会报错。暂停、恢复和停止的功能也是在该函数中实现的。

 

我们知道在终端上运行python时,可以通过ctrl + c 来终止运行的python脚本,并且会弹出很多信息。我们的停止功能和这个相同,不过还有另一种接口调用。停止功能的函数需要返回-1,,并且调用PyErr_SetInterrupt()或PyErr_SetString(PyExc_KeyboardInterrupt, "Abort")。调用第一个是直接停止python解释器,不带有返回信息;调用第二个相当于使用ctrl + c来终止程序,带有返回信息,对用户输出内容这里包含About。异常停止的函数由c api Py_AddPendingCall()来调用。这里需要注意的是Py_AddPendingCall()该函数需要和python执行PyRun_SimpleString()的调用在同一个线程里面。

暂停的功能则是在调用每条指令前进行拦截。

 

 

为了防止自定义python中执行while 耗时操作,故将PyRun_SimpleString()放在线程中执行,这样就不会阻塞UI界面了。而我们也将回调函数注册到了线程里面。

这里面要注意的是当停止按钮按下后,被中断的线程需要根据对应的业务逻辑做对应的处理,有关线程的处理是很有考究的。

 

如果大家想要工程源码,可以在公众号后台留言。欢迎大家交流分享。

 

 

 

微信扫一扫
关注该公众号

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值