Differences Between Threads and Processes


Motivation

The difference between threads and processes used to confused me. Why do we need threads since we already have processes to support concurrency? What’s the mechanism of the context switch between threads?(rather than processes) How is locks implemented? This article may be your answer.

Acknowledgement: Some of the sentences and graphs are taken from <Operating System Concepts 7th edition> written by Silberschatz, G. G. and the sildes of CS422 conducted by Zhong Shao, Yale University.

Why processes

Early computer only allowed one program to be executed at a time. This program had complete control of the CPU and had access to all the system’s resources. It works and is simple, intuitive, but nasty.

Actually it’s unfair to claim that a CPU running only one program is nasty. Indeed, it’s often the case in embedded system that the MCU (micro control unit) only runs one program with the support of several interrupt vectors. But it is another story which won’t be covered in this article.

There are several cons if a computer can only run one program at a time:

  1. The speed of I/O is dramatically slow compared to the speed of CPU. CPU has to halt to wait for I/O.
  2. It doesn’t support multiple tasks. Say I can’t type this article and listen to music at the same time.

 

Context Switch between processes

PCB(process control block), Page table, Open file handles all need to be stored and switched.

 

Why threads

Context switch between threads is much more efficient comparing with that between processes. The overhead of creating a thread is also much smaller.

Pros of using a thread

  1. Economic
    1. The overhead of creating a thread is small. We don’t need to create a new page table for it. All the threads within a same process shares a same page table.
  2. Responsive
    1. The context switch of threads is faster, which leads to high responsive ability. Say, in server softwares, one thread listens to an port. Whenever a new request of a client comes, it will spawn a new thread to handle this request.
  3. Share data(communicate)
    1. All threads within the same process shares heap space together.

Context switch in threads

4 functions related to context switch

  1. thread_create(thread, func, args) – create a new thread to run func(args)
  2. thread_yield() – relinquish processor voluntarily
  3. thread_join(thread) – In parent, wait for forked thread to exit, then return
  4. thread_exit() – quit thread and clean up, wake up joiner if any

Thread context can be classified into two types:

  • private state
    • program counter
    • registers
    • stack
  • shared
    • contents of memory (global variables, heap)
    • file system

Classifying program variables

int x; // global variable

void foo(){
  int y; //stack variable
  x = 1;
  y = 1;
}

main(){
  int *p;
  p = (int *)malloc(sizeof(int));
  * p = 1; //head access
}
  • Addresses of global variables are defined at link-time
  • Addresses of heap variables are defined at run-time(malloc-time)
  • Addresses of stack variables are defined at call-time

Thread control block (TCB)

TCB stores the following info

  • current state
    • ready: ready to run
    • running: currently running
    • waiting: waiting for resources(I/O, locks, etc.)
  • registers
  • status(EFLAGS)
  • program counter(EIP)
  • stack

Screenshot from 2015-10-05 13:56:46

 

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.