Before We Start...
This tutorial is an attempt to help you become familiar with multi-threaded programming with the POSIX threads
(pthreads) library, and attempts to show how its features can be used in "real-life" programs. It explains the different
tools defined by the library, shows how to use them, and then gives an example of using them to solve programming
problems. There is an implicit assumption that the user has some theoretical familiarity with paralell programming (or
multi-processing) concepts. Users without such background might find the concepts harder to grasp. A seperate tutorial
will be prepared to explain the theoreticl background and terms to those who are familiar only with normal "serial"
programming.
I would assume that users which are familiar with asynchronous programming models, such as those used in
windowing environments (X, Motif), will find it easier to grasp the concepts of multi-threaded programming.
When talking about POSIX threads, one cannot avoid the question "Which draft of the POSIX threads standard shall be
used?". As this threads standard has been revised over a period of several years, one will find that implementations
adhering to different drafts of the standard have a different set of functions, different default values, and different
nuances. Since this tutorial was written using a Linux system with the kernel-level LinuxThreads library, v0.5,
programmers with access to other systems, using different versions of pthreads, should refer to their system's manuals
in case of incompatibilities. Also, since some of the example programs are using blocking system calls, they won't
work with user-level threading libraries (refer to our
parallel programming theory tutorial for more information).
Having said that, i'd try to check the example programs on other systems as well (Solaris 2.5 comes to mind), to make it
more "cross-platform".
What Is a Thread? Why Use Threads
A thread is a semi-process, that has its own stack, and executes a given piece of code. Unlike a real process, the thread
normally shares its memory with other threads (where as for processes we usually have a different memory area for
each one of them). A Thread Group is a set of threads all executing inside the same process. They all share the same
memory, and thus can access the same global variables, same heap memory, same set of file descriptors, etc. All these
threads execute in parallel (i.e. using time slices, or if the system has several processors, then really in parallel).
The advantage of using a thread group instead of a normal serial program is that several operations may be carried out
in parallel, and thus events can be handled immediately as they arrive (for example, if we have one thread handling a
user interface, and another thread handling database queries, we can execute a heavy query requested by the user, and
still respond to user input while the query is executed).
The advantage of using a thread group over using a process group is that context switching between threads is much
faster than context switching between processes (context switching means that the system switches from running one
thread or process, to running another thread or process). Also, communications between two threads is usually faster
and easier to implement than communications between two processes.
On the other hand, because threads in a group all use the same memory space, if one of them corrupts the contents of its
memory, other threads might suffer as well. With processes, the operating system normally protects processes from one
another, and thus if one corrupts its own memory space, other processes won't suffer. Another advantage of using
processes is that they can run on different machines, while all the threads have to run on the same machine (at least
normally).
Creating And Destroying Threads
http://users.actcom.co.il/~choo/lupg/tutorials/multi-thread/multi-thread.html (2 of 22) [01/04/2003 09:52:59 a.m.]