[Tutor] threads
Jeff Shannon
jeff@ccvcorp.com
Mon Jan 13 15:13:06 2003
Scott wrote:
>On Mon, 13 Jan 2003 03:34:16 -0800 (PST)
>Danny Yoo <dyoo@hkn.eecs.berkeley.edu> wrote:
>
>>Empirically, it seems that multithreaded programs can be either easy
>>or difficult, based on design. Personally, I think they're hard. As
>>a concrete anecdote: the source to the excellent classic game "Star
>>Control II" has just been released to the public,
>>
>>
>
>If *you* think they're hard, maybe I ought to stay far away from them!
>But looks like for the program I'm trying to create, I have no choice
>really.
>
IMO, threading can be anywhere from moderately straightforward to
incredibly brainbending, depending on just how you're using those
threads. The trick is to remember that you can't be sure of the timing
of *anything* that happens in another thread unless you explicitly
synchronize. For most purposes, synchronizing threads isn't all that
difficult, but if you're doing something complex then the
synchronization issues can quickly become extremely hairy.
One resource that is invaluable for multithreading is the Queue module.
Queues are threadsafe methods of passing data back and forth between
threads. (Sharing a normal variable between threads is *not* safe,
because you can never tell when the other thread might clobber your
variable while you're in the middle of using it...) One of the standard
architectures for multithreading is to designate a set of "producer"
threads and a set of "consumer" threads. Since you mention sockets, one
possibility is to hand a socket and one end of a queue to each producer
thread. That thread will read data from the socket, package it up, and
drop it into the queue. You can safely have several such threads
dropping data into the same queue. Now you set up a consumer thread
that reads data from the queue and then acts on it. It'll need to keep
track of *which* socket the data came from (so that information needs to
be in the packaging), but it doesn't need to worry about *how* to get
the data. The synchronization trick comes in because you have no way of
knowing which data arrived "first", only what socket it came from -- and
you can be pretty sure (if you're using TCP sockets at least) that the
data from any given socket is in order. But if (for example) you're
receiving long streams of data on two different sockets, you can't be
sure that you'll get all of stream 1 before stream 2, or vice versa --
probably you'll get both streams in many small chunks that are somewhat
randomly interleaved.
So, again, the trick with threads is to never trust the timing of
anything, and to be careful any time that threads are doing anything
that might be interpreted as sharing information. And be wary of the
possibility that thread A may be waiting for thread B to provide some
data, but thread B is blocked waiting for a resource that thread A has
locked up...
But yes, try it out a bit, keep it simple at first, and feel free to ask
specific questions here. :)
Jeff Shannon
Technician/Programmer
Credit International