[Tutor] threading vs. forking?
Jeff Shannon
jeff@ccvcorp.com
Thu Jul 10 13:24:01 2003
Thomas CLive Richards wrote:
>Hi,
>
>I'm *trying* to develop a program which (amongst other things) reads
>information from a serial port and prints it in a nice GUI interface.
>
>[...]
>
>So, AFAIK, there are two methods around this. there are probably many
>more ways to do this, but i haven't a clue what they are.
>
>The first would be forking the process using os.fork(), and running the
>serial port polling in one fork, and the GUI in another, and somehow
>send the data to the GUI.
>
>the other would be using threading. The problem with that is that I've
>never done it before, and from reading the documentation, I can't see
>how to get information from one thread to another. There is likely to be
>a lot of information on the port, so the information passing would have
>to be easy...
>
If you fork, then you have two independent processes, which need to talk
to each other in some way. You could set up a pipe or a socket
connection. However, you'll then have the same problem talking to the
pipe/socket that you currently have talking to the serial port directly
-- you'll need *some* method of polling to see when there's new data there.
Threads are probably your best / most robust option here. There's a
number of different ways to pass data back and forth between threads;
the most robust of those is the Queue module. Queues are automatically
thread-safe -- hand one end of the Queue to each thread. The worker
thread can sit in a loop polling the serial port; when something comes
in, it packages up the data and drops it in the Queue. The GUI thread
checks the queue when it has a chance (either in a timer event or an
idle handler), and if there's data there it pulls it out and processes
it. The queue will make sure that the data is retrieved in the same
order that it's inserted, and that nothing gets overwritten or otherwise
mangled. If you need to also send from your serial port, as well as
receive, you can have another Queue that goes in the other direction.
Your worker thread would then alternate between checking if there's
data to read on the serial port, and checking if there's anything in the
Queue that it should send on the serial port. Note that a worker thread
cannot be killed from the main thread -- if you want a worker thread to
end before the entire program shuts down, that thread needs to end on
its own, so you may want to have some way to ask that thread to commit
suicide. This could be a matter of sending a special token in the
output-queue, if you have one, or it could be an independent threading
signal.
One other possibility, depending on the constraints of your application,
would be to forget about threading and just check the serial port
directly from a timer event. You can look at the serial port, say, ten
times per second, and read any data that's waiting there. However, this
method is far more likely to be delayed and possibly miss data -- if
serial data comes in faster than you're reading it, you'll overflow the
serial port buffer and lose data. But that might not really be an issue
-- if you're reading a scale, and are just grabbing the current weight,
it probably doesn't matter much if you miss a sample or two.
Jeff Shannon
Technician/Programmer
Credit International