Knowing how to properly use threads should be part of every computer science
and engineering student repertoire.
This tutorial is an attempt to help you become familiar with multi-threaded
programming with the POSIX (Portable Operating System Interface) threads, or
pthreads. This tutorial explains the
different tools defined by the pthread library, shows how to use them, and
gives examples of using them to solve real life programming problems.

Technically, a thread is defined as an independent stream of instructions that can
be scheduled to run as such by the operating system.

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).

One area in which threads can be very helpful is in user-interface programs.
These programs are usually centered around a loop of reading user input,
processing it, and showing the results of the processing. The processing part
may sometimes take a while to complete, and the user is made to wait during
this operation. By placing such long operations in a separate thread, while
having another thread to read user input, the program can be more responsive.
It may allow the user to cancel the operation in the middle.

Example 2: A graphical interface

In graphical programs the problem is more severe, since the application
should always be ready for a message from the windowing system telling it
to repaint part of its window. If it's too busy executing some other
task, its window will remain blank, which is rather ugly. In such a case,
it is a good idea to have one thread handle the message loop of the windowing
systm and always ready to get such repain requests (as well as user input).
Whenever this thread sees a need to do an operation that might take a long
time to complete (say, more then 0.2 seconds in the worse case), it will
delegate the job to a separate thread.

Example 3 : A Web server

It needs to handle several download requests over a short period

Hence more efficient to create (and destroy) a single thread for each request

Multiple threads can possibly be executing simultaneously on different processors

When a multi-threaded program starts executing, it has one thread running,
which executes the main() function of the program. This is already a
full-fledged thread, with its own thread ID. In order to create a new thread,
the program should use the
pthread_create() function.
Here is how to use it:

Understanding the simple threaded program above.
While it does not do anything useful, it will help you understand how threads work. Let us
take a step by step look at what the program does.

In main() we declare a variable called
thread_id, which
is of type pthread_t.
This is basically an integer used to identify the
thread in the system.
After declaring thread_id, we call the pthread_create()
function to create a real, living thread.

pthread_create()
gets 4 arguments The first argument is
a pointer to thread_id, used by pthread_create()
to supply the program with the thread's identifier.
The second argument is used to set some
attributes for the new thread. In our case we supplied a NULL pointer to
tell pthread_create() to use the default values.
Notice that PrintHello() accepts a void * as an argument and
also returns a void * as a return value. This shows us that it is possible
to use a void * to pass an arbitrary piece of data to our new thread, and
that our new thread can return an arbitrary piece of data when it finishes.
How do we pass our thread an arbitrary argument? Easy. We use the fourth
argument to the pthread_create() call. If we do not want
to pass any data to the new thread, we set the fourth argument to NULL.
pthread_create() returns zero on success and a non-zero value
on failure.

After pthread_create() successfully returns, the program will consist of
two threads. This is because the main program
is also a thread and it executes the code in the
main() function in parallel to the thread it creates.
Think of it this way: if you write a program that does not use POSIX threads
at all, the program will be single-threaded (this single thread is called
the "main" thread).

The call to pthread_exit() causes the current thread
to exit and free any thread-specific resources it is taking.

In order to compile a multi-threaded program using gcc,
we need to link it with the pthreads library. Assuming you have this library
already installed on your system, here is how to compile our first program: