Threading question

I have a long-running application written in C. (It's a neural net.) I have wrapped it as a python extension and am calling it via a wxPython app. Everything works fine except that the GUI freezes when the extension runs.

I have read and appreciated the LongRunningTasks entry in wxPython Wiki.
However my needs are slightly different in that I have no mechanism
in my C code to return control to wxPython/python. In the tutorial there
were a number of small "Worker Bees" which terminated... here I have a
monolithic neural net simulator that does not, on it's own, terminate until it has processed some number of epochs. Say 10 seconds.

What I would like to do is call some callback function inside the
inner loop so that things are more responsive. I presume I can pass wxYield as a callback function into my C extension via the mechanism described in the Python documention on C/C++ API and C/C++ extension.
But I don't really understand it. Moreover I'm not sure I need to go
to this trouble. Maybe I can just link against the appropriate threading
libraries in linux and windows and just call some yield() function.

Anyway, what I want is to stop my neural network simulator every, say,
100Milliseconds to allow any window updates and allow a "PAUSE" button to stop execution.

What is the easiest way to achieve this?

Any help is appreciated.

Cheers,
Doug Eck.

I seem to have solved this by passing in a callback function from the wrapper code
(that defines the python interface) into the main code for the network.

static void do_callback() {
    PyEval_CallObject(pyCbFunction, arglist); //where pyCbFunction is passed in from python.
  }

  static PyObject * rete_learn(PyObject * self, PyObject * args) {
    int * dims=new int[16];
    int numDims=0;
    char *argStr;
    if (!PyArg_ParseTuple(args, "", &argStr))
      return NULL;

       //set the callback
    do_callback();
    net->setCallback((void (*)(void)) do_callback);
  ...
}

Thanks!

Douglas Eck wrote:

···

I have a long-running application written in C. (It's a neural net.) I have wrapped it as a python extension and am calling it via a wxPython app. Everything works fine except that the GUI freezes when the extension runs.

I have read and appreciated the LongRunningTasks entry in wxPython Wiki.
However my needs are slightly different in that I have no mechanism
in my C code to return control to wxPython/python. In the tutorial there
were a number of small "Worker Bees" which terminated... here I have a
monolithic neural net simulator that does not, on it's own, terminate until it has processed some number of epochs. Say 10 seconds.

What I would like to do is call some callback function inside the
inner loop so that things are more responsive. I presume I can pass wxYield as a callback function into my C extension via the mechanism described in the Python documention on C/C++ API and C/C++ extension.
But I don't really understand it. Moreover I'm not sure I need to go
to this trouble. Maybe I can just link against the appropriate threading
libraries in linux and windows and just call some yield() function.

Anyway, what I want is to stop my neural network simulator every, say,
100Milliseconds to allow any window updates and allow a "PAUSE" button to stop execution.

What is the easiest way to achieve this?

Any help is appreciated.

Cheers,
Doug Eck.

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwindows.org
For additional commands, e-mail: wxPython-users-help@lists.wxwindows.org

I'm not really a C coder, but I think you may be making this a little too complex? You pass in an object to the "learning" object (I don't see where you're actually storing the pointer in this code fragment, however). You then want to do a callback to that object. Basically, the steps would be:

To specify the callback:
    Parse the args tuple object to get a simple object pointer PyObject * callback. I believe the format you're looking for is "sO" for the PyArg_ParseTuple (I'm going by memory there, however), with the address of your callback variable as an argument to the function after argstr.
    INCREF your pointer to the callback object (so it won't disappear).
    Store the pointer anywhere you like as a PyObject * accessible to your long-running functions.

To do the callback (check whether to continue, and allow processing while running):
    Create a PyObject * to another tuple of "args" with your callback arguments and INCREF it (if len(args) == 0, then you can skip this and just use NULL for args). Check for NULL results when constructing this tuple (errors).
    Do a *PyObject_CallObject*( callback, args), capturing the result as another PyObject *.
    Check the value returned to determine whether to stop processing (check for NULL result as well and raise errors if result == NULL).
    DECREF the result object.
    DECREF your args tuple (if it isn't NULL).

To exit the long-running process (even if it's because of an error condition):
    DECREF the callback object pointer (assuming you already incref'd it).

HTH,
Mike

Douglas Eck wrote:

···

I seem to have solved this by passing in a callback function from the wrapper code
(that defines the python interface) into the main code for the network.

static void do_callback() {
   PyEval_CallObject(pyCbFunction, arglist); //where pyCbFunction is passed in from python.
} static PyObject * rete_learn(PyObject * self, PyObject * args) {
   int * dims=new int[16];
   int numDims=0;
   char *argStr;
   if (!PyArg_ParseTuple(args, "", &argStr))
     return NULL;

     //set the callback
   do_callback();
   net->setCallback((void (*)(void)) do_callback);
...
}

Thanks!

Douglas Eck wrote:

I have a long-running application written in C. (It's a neural net.) I have wrapped it as a python extension and am calling it via a wxPython app. Everything works fine except that the GUI freezes when the extension runs.

I have read and appreciated the LongRunningTasks entry in wxPython Wiki.
However my needs are slightly different in that I have no mechanism
in my C code to return control to wxPython/python. In the tutorial there
were a number of small "Worker Bees" which terminated... here I have a
monolithic neural net simulator that does not, on it's own, terminate until it has processed some number of epochs. Say 10 seconds.

What I would like to do is call some callback function inside the
inner loop so that things are more responsive. I presume I can pass wxYield as a callback function into my C extension via the mechanism described in the Python documention on C/C++ API and C/C++ extension.
But I don't really understand it. Moreover I'm not sure I need to go
to this trouble. Maybe I can just link against the appropriate threading
libraries in linux and windows and just call some yield() function.

Anyway, what I want is to stop my neural network simulator every, say,
100Milliseconds to allow any window updates and allow a "PAUSE" button to stop execution.

What is the easiest way to achieve this?

Any help is appreciated.

Cheers,
Doug Eck.

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwindows.org
For additional commands, e-mail: wxPython-users-help@lists.wxwindows.org

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwindows.org
For additional commands, e-mail: wxPython-users-help@lists.wxwindows.org

--
_______________________________________
  Mike C. Fletcher
  Designer, VR Plumber, Coder
  http://members.rogers.com/mcfletch/