Friday, June 11, 2004

The History of threads

Threads have not always been around. The first versions of Unix only had processes. Versions of Windows prior to Windows 95 didn't even have processes. The Usenet group FAQ for comp.os.research has an excellent history of threads.

Prior to the development of threads the developer was limited to using processes. A process is a heavyweight object that includes its own memory space, code space, heap space, and stack space. This means that if you needed to do a task in the background you had two choices:

1. You could spawn an entirely new process. Since a process has its own memory space you needed to develop a means of communicating between the two processes. Some of the choices were, shared memory, signals, shared files, pipes, or sockets. All of these approaches were very complex and difficult to get right. On top of that these means of "interprocess communication" were all heavy weight.

On older Unix systems you had the problem of Zombie processes which couldn't be killed. These were caused by one process spawning another and then not cleaning up properly.

2. You could emulate a backgroud task through a message loop style design. In this case you had an infinite loop that serviced a queue of tasks. Work ot be done was added to the queue. You were really implementing your own multitasking layer on top of the OS. This is techique used by the evil Motif Widgets package as well as all versions of Microsoft Windows prior to Windows 95.

As you can see implementing a background task was a significant effort. This was not as bad as it sounds. It forced developers to think through their designs. Only the most worthy of uses for background tasks were actually implemented. Again this is good since the use of background tasks is easily an order of magnitude more difficult and complex than single threaded programming.

Work on operating systems that supported threads began in the mid-1960's. Threading packages began to show up in in mainstream Unix releases in the early 1980's.

Threads were hailed as the solution to many problems in systems development. A thread has its own stack and address pointer, but shares the memory space and heap of its parent task. Communication between threads is within the same task. Communication can be as easy as pointing to a common place in memory. (Sure it is ...)

What most folks don't understand is that all threads did was to lower the barrier to creating multi-tasking applications. It did nothing to make multi-tasking development any easier. Using multiple threads is still that order of magnitude more difficult than single threading.

I like to think of the emergence of threads like this. Imagine if a cheap, easy, and widely available means of creating weapons grade uranium were to be found. Everyone with a little bit of initiative could churn our kilograms of this material. Would this be good for the world? Would there be folks who have no business messing with this material be playing with it? Would there be some idiot trying to find a way to integrate it into a childs toy?

I would not want to go back to systems without threads, but it only made the job of software project management more difficult.

Friday, June 04, 2004

The Threads thread: The common abuse of a fine idea

As promised in the byline of this blog I am going to address a common architectural/design blunder: The misuse of threads. I have seen this so often, and have seen it impair code performance that I feel something must be said. I am not the first voice to say these things. However given the magnitude of the issue the perils cannot emphasized enough.

I will present the case for care with threads as follows;

1. The history of threads

2. Threads impair performance

3. Threads increase design/implementation/debug time

4. Threads are not an architectural element

5. The proper use of threads