Introduction to concurrency using threads


Review: process calls fork()


Review: process context switch


Example: web server

1
2
3
4
5
6
7
8
while (1) {
	  int sock = accept();
  if (0 == fork()) {
    handle_request();
    close(sock);
    exit(0);
  }
}

Thread: a new abstraction for running processes


Thread: state of a single thread


Example: web server using thread

1
2
3
4
5
6
7
8
9
10
11
12
13
int global_counter = 0;
web_server() {
  while (1) {
    int sock = accept();
    thread_create(handle_request, sock);
  }
}

handle_request(int sock) {
  process request;
  ++global_counter;
  close(sock);
}

API: POSIX threads (pthreads)


Hands on: say hello to my little threads …

1
2
mkdir ~/concurrency
cd ~/concurrency
1
2
3
4
gcc -o thread_hello thread_hello.c -lpthread
./thread_hello 1
./thread_hello 2 
./thread_hello 4

The problem with threads

Edward Lee (2006). The Problem with Threads. Computer 39(5).

From a fundamental perspective, threads are seriously flawed as a computation model because they are wildly nondeterministic… The programmer’s job is to prune away that nondeterminism. We have developed tools to assist in the pruning: semaphores, monitors, and more modern overlays on threads offer the programmer ever more effective pruning. But pruning a wild mass of brambles rarely yields a satisfactory hedge. To offer another analogy, a folk definition of insanity is to do the same thing over and over again and expect the results to be different. By this definition, we in fact require that programmers of multithreaded systems be insane. Were they sane, they could not understand their programs.


Challenge