When a task has two or more semi-independent subtasks, multiple
threading can increase throughput, give better response time, speed
operations, improve program structure, use fewer system resources,
and make more efficient use of multiprocessors. With multi-threading,
a process has many threads of control. Note, order of execution
is still important!
The following terminology will be useful to understand multi-threading:
- User threads
- Handled in user space and controlled using the threads
APIs provided in the threads library. Also referred to as user-level
or application-level threads. 
- Kernel threads
- Handled in kernel space and created by the thread
functions in the threads library. Kernel threads are kernel schedulable
entities visible to the operating system. 
- Lightweight processes (LWPs)
- Threads in the kernel that execute kernel code and
system calls. 
- Bound threads
- Threads that are permanently bound to LWPs. A bound
thread is a user thread bound directly to a kernel thread. Both
a user thread and a kernel-scheduled entity are created when a bound
thread is created.  
- Unbound threads
- Threads that attach and detach from among the LWP
pool. An unbound thread is a user thread that can execute on top
of any available LWP. Bother bound and unbound threads have their
advantages and disadvantages, depending entirely on the application
that uses them. 
- Concurrency
- At least two threads are in progress at the same
time 
- Parallelism
- At least two threads are executing simultaneously.