Stop inline python

I am embedding python in a C ++ plugin. The plugin invokes the python algorithm dozens of times during each session, each time sending the algorithm to different data. So far so good

But now I have a problem: The algorithm takes several minutes to solve and return the solution, and during this time the conditions often change, making this solution insignificant. Therefore, I want to stop the algorithm from starting at any time and start it immediately after using another data set.

Here is the C ++ code for embedding python that I still have:

void py_embed (void*data){


counter_thread=false;

PyObject *pName, *pModule, *pDict, *pFunc;

//To inform the interpreter about paths to Python run-time libraries
Py_SetProgramName(arg->argv[0]);

if(!gil_init){
    gil_init=1;
    PyEval_InitThreads();
    PyEval_SaveThread();
}
PyGILState_STATE gstate = PyGILState_Ensure();

// Build the name object
pName = PyString_FromString(arg->argv[1]);
if( !pName ){
    textfile3<<"Can't build the object "<<endl;
}

// Load the module object
pModule = PyImport_Import(pName);
if( !pModule ){
    textfile3<<"Can't import the module "<<endl;
}

// pDict is a borrowed reference 
pDict = PyModule_GetDict(pModule);
if( !pDict ){
    textfile3<<"Can't get the dict"<<endl;
}

// pFunc is also a borrowed reference 
pFunc = PyDict_GetItemString(pDict, arg->argv[2]);
if( !pFunc || !PyCallable_Check(pFunc) ){
    textfile3<<"Can't get the function"<<endl;
}

/*Call the algorithm and treat the data that is returned from it
 ...
 ...
 */

// Clean up
Py_XDECREF(pArgs2);
Py_XDECREF(pValue2);
Py_DECREF(pModule);
Py_DECREF(pName);

PyGILState_Release(gstate);

counter_thread=true;
_endthread(); 

};

Edit: python algorithm is not my job and I should not change it

+4
source share
4 answers

python python.

PyThreadState_SetAsyncExc python.

python - . PyGILState_STATE, PyThreadState_SetAsyncExc . ( , python 2- ).

python, , "catch alls", .

- python, script, .

Py_AddPendingCall , , , .

+5

, . python (, - ), PROCESS ( ipc ). api, .

+4

, , , ( ).

, , , - T1 -, -T2 - , .

:

thread_counter+=1; //global variable
int thisthread=thread_counter;

, python, , "", T1 T2:

if(thisthread==thread_counter){
     /*save the solution and treat it */
}

, , .

+2

, , - https://docs.python.org/2/c-api/init.html#sub-interpreter-support. . , .

- python multiprocessing, - (- time_to_die). GIL, , GIL .

But then another idea came to me. Why not just use fork (), initialize your python interpreter in the child, and when the parent decides how long the end of python ends, just kill it. Something like that:

void process() {

    int pid = fork();
    if (pid) {
        // in parent
        sleep(60);
        kill(pid, 9);   
        }
    else{
        // in child
        Py_Initialize();
        PyRun_SimpleString("# insert long running python calculation");
        }
    }

(This example assumes * nix, if you are running on Windows, replace CreateProcess () / TerminateProcess ())

+2
source

Source: https://habr.com/ru/post/1545286/


All Articles