Threading
Posted: Wed Dec 10, 2008 9:48 pm
Hopefully writing this out will help me understand it a bit more... and to get some feedback.
Goals of threading:
* Prevent the gui from becoming unresponsive during large amounts of serial activity. Currently caused by packet decoding running in the same thread
* Prevent large send or receive actions locking up the serial connection for the other
* Have the serial connection constantly monitored, not just during gui idle event as it is currently
Limitations:
* Reading/writing to serial connection cannot be done by two separate threads due to locking.
* Running any method (except the run() method) in a thread, will lock up the calling thread while its being run. Hence all non-near-instant processing should be kept in the run() method (packet to/from raw bytes processing!).
Pythonisms:
* A class can be threaded by extending the thread class.
* The __init__ method will be run, followed by the run() method of the class.
* The thread terminates when the run method does, so in essence only the run() method is threaded
* Either the threads must be notified of program shutdown, or run in daemon mode in which they will be terminated on parent thread completion.
* Other methods of the threaded class can be run from other threads
* Python has condition objects for locking, waiting, notifying logic
My current idea:
* One thread for serial, one for receive, one for send, one for gui.
* Serial thread will have a send queue, containing raw packets. The run() method will process the oldest packet in the queue, check the receive buffer, send any receive buffer to the receive thread, then loop again. Does it need to sleep between loops? The serial thread must keep the connected flag up-to-date, as other threads will poll this continuously, and cant wait for the run() method to answer.
* The send thread will use the current protocol interface, but instead of sending packets in each method. It will add them to a queue for processing. The run() method will loop through this queue, creating raw packets, which will then be appended to the serial thread send queue.
* The receive thread will append all raw buffer received from the serial thread to its own buffer, and process this buffer in the run() method. It would then send completed packet objects to the gui thread which would offload them to any watching classes.
* The gui thread would do its gui thing, send packet classes to the send thread, and receive packet classes from the receive thread reading for dispersing to watching classes.
* Gui methods that need to wait for responses, will need to set up wxPython events, and the receive thread will need to have the functionality to raise events.
Hope that all makes sense. Writing it out at least has helped a lot for me
Goals of threading:
* Prevent the gui from becoming unresponsive during large amounts of serial activity. Currently caused by packet decoding running in the same thread
* Prevent large send or receive actions locking up the serial connection for the other
* Have the serial connection constantly monitored, not just during gui idle event as it is currently
Limitations:
* Reading/writing to serial connection cannot be done by two separate threads due to locking.
* Running any method (except the run() method) in a thread, will lock up the calling thread while its being run. Hence all non-near-instant processing should be kept in the run() method (packet to/from raw bytes processing!).
Pythonisms:
* A class can be threaded by extending the thread class.
* The __init__ method will be run, followed by the run() method of the class.
* The thread terminates when the run method does, so in essence only the run() method is threaded
* Either the threads must be notified of program shutdown, or run in daemon mode in which they will be terminated on parent thread completion.
* Other methods of the threaded class can be run from other threads
* Python has condition objects for locking, waiting, notifying logic
My current idea:
* One thread for serial, one for receive, one for send, one for gui.
* Serial thread will have a send queue, containing raw packets. The run() method will process the oldest packet in the queue, check the receive buffer, send any receive buffer to the receive thread, then loop again. Does it need to sleep between loops? The serial thread must keep the connected flag up-to-date, as other threads will poll this continuously, and cant wait for the run() method to answer.
* The send thread will use the current protocol interface, but instead of sending packets in each method. It will add them to a queue for processing. The run() method will loop through this queue, creating raw packets, which will then be appended to the serial thread send queue.
* The receive thread will append all raw buffer received from the serial thread to its own buffer, and process this buffer in the run() method. It would then send completed packet objects to the gui thread which would offload them to any watching classes.
* The gui thread would do its gui thing, send packet classes to the send thread, and receive packet classes from the receive thread reading for dispersing to watching classes.
* Gui methods that need to wait for responses, will need to set up wxPython events, and the receive thread will need to have the functionality to raise events.
Hope that all makes sense. Writing it out at least has helped a lot for me