Threads
A thread is a control point, essentially a place in the instruction sequence. Multiple control points are possible within the same process: it's like having multiple program counters. In actuality, each thread will have it's own program counter (current instruction to execute) and it's own stack (local variables) and stack frame pointer (currently called function) and a few minor additional things. The address space and all process structures are shared, that is, the code, global variables, malloc arena, open files, current directory and so on are shared.

Separate threads are often used instead of separate processes. Starting a new thread is much faster and uses far fewer system resources than starting a new process. Moreover, separate threads can communicate more easily with each other than separate processes. Many better modern kernels and various utilities, for example those in Solaris, are highly threaded. Typically, database managers, transaction processors, network protocol programs, GUIs and server code in the kernel are multithreaded. Good candidates for multithreading are: servers, programs with many independent tasks, programs with repetitive tasks, and "vectorizable" programs. Bad candidates are: simple programs, ones where tasks are tightly interconnected, or ones with very independent tasks (write as separate programs instead). The danger in multithreading is the temptation to write "bloatware" such as the leading web browsers and office suites.

The reasons for multithreading a program are:

Threads exist and can be implemented at several levels.

User thread libraries are faster to set up than LWP's and may run faster because no system calls are used. Functionality is implemented at user level instead of at the system call level. Asynchronous difficulties are hidden in the library and the user has a relatively simple interface to deal with. Once the application is written, if desired, it is fairly easy to change the application to use LWP's instead.

A process can have several underlying LWP's. Several user threads may be multiplexed over a few LWP's. Some threads (for example, a thread associated with a mouse) can be run at higher priority that other threads.

There are system programming problems with threads:

To control access to global variables and shared resources, various synchronization primitives are used:

 
POSIX Threads
Reference: Multithreaded Programming with Pthreads, by B. Lewis and D. Berg, Prentice Hall, 1998.
pthread_create(start_function, arg structure) creates a thread, invoking start_function and passing data via arg structure.
pthread_exit(  ) or a return from start_function ends a thread. exit must not be used as it will kill the entire process, not just the current thread.
pthread_cancel(  ) kills some thread.
pthread_join(  ) allows one thread to wait for another.
Note the following correspondence between UNIX process related system calls and thread calls, however, the syntax is very different. There is no thread analogue to pipe since pipe is an inter process communication call and is not needed. Similarly exec has no analogue as an exec would replace the code for all threads and typically threaded code is self contained.
Process call   Thread call
fork pthread_create
exit pthread_exit
kill pthread_cancel
waitpid pthread_join
In Win32 threads (not POSIX) the following are used: CreateThread, _beginthreadx, or _beginthread; ExitThread, _endthreadx, or _endthread; TerminateThread; WaitForSingleObject. These are analogues to NT's CreateProcess and ExitProcess.

Last update: 2001 April 9