pybind11 icon indicating copy to clipboard operation
pybind11 copied to clipboard

[QUESTION] How to execute on other thread and stop execution by user

Open paulocoutinhox opened this issue 5 years ago • 5 comments

Hi,

I made a simple sample that:

  1. Start a C++ thread
  2. Execute python code with pybind11 in the thread created
  3. Check if "stopped" variable is true and interrupt execution

Sample: https://github.com/prsolucoes/pybind11-test/blob/master/src/cpp/main.cpp#L26-L35

The problem: The line "py::exec(content);" block thread execution and i need that it stop run when "stopped" variable is "true".

Question: How can i execute the python code and stop it while it is running correctly?

Thanks.

paulocoutinhox avatar Nov 18 '20 19:11 paulocoutinhox

Move it to another thread any way you want to; this is independent of pybind11. And make sure you there acquire the GIL, before running py::exec. Then from your main thread, you should check for user input and try with the PyErr_SetInterrupt that I advised in #2631.

Probably. I don't know about your application and how it's linked to the UI, but yes, py::exec blocks, so you need to do threading yourself.

YannickJadoul avatar Nov 18 '20 22:11 YannickJadoul

Oh, you already have a thread? Well, don't call PyErr_SetInterrupt from the same thread as you're running py::exec, or it won't be able to interrupt anything. Put it in this while (!executed) loop, probably?

YannickJadoul avatar Nov 18 '20 22:11 YannickJadoul

How can i Interrupt the python interpreter with excute eval_file ?

luodaoyi avatar Apr 10 '23 14:04 luodaoyi

I'm in the same situation. Is there any update on this issue

rhvarrier avatar Apr 20 '24 18:04 rhvarrier

I used PyEval_SetTrace and it works in my case. Something like this

int InteruptCheck(PyObject* obj, _frame* frame, int what, PyObject* arg)
{
    if (g_Interupt) // Set g_Interupt global variable to cancel script
    {
        PyErr_SetString(PyExc_KeyboardInterrupt, "Stop script");
        g_Interupt = false;
    }

    return 0;
}

void YourFunction()
{
  PyEval_SetTrace(InteruptCheck, NULL);
  // Run python script here
  PyEval_SetTrace(NULL, NULL);
}

ElvisBlue avatar Apr 21 '24 04:04 ElvisBlue