Lecture 5: Threads

Previous lecture Next lecture

Exam

Threads as a lightweight abstraction and process alternative

Important questions:

Lightweight processes - threads

Threads example

Threads in Windows

Threads in Windows (2)

Threads in Linux

Linux system call: int __clone(in (*fn)(void*), void *stack, int flags, void *arg) Universal function, parameterized using the flags parameter:

_ Description
CLONE_VM use a common address space
CLONE_FS share information about the file system
CLONE_FILES share file descriptors (open files)
CLONE_SIGHAND share the signal handler table

Threads in Linux (2)

Fibers

Inspiration: Duff's device

send(short *to, *from, int count)
{
  do { /* count > 0 assumed */
    *to = *from++;
  } while (--count > 0);
}
send(short *to, *from, int count)
{
  register n = count / 8;
  do {
    *to = *from++;
    *to = *from++;
    *to = *from++;
    *to = *from++;
    *to = *from++;
    *to = *from++;
    *to = *from++;
    *to = *from++;
  } while (--n > 0);
}
send(short *to, *from, int count)
{
  register n = (count + 7) / 8;
  switch (count % 8) {
  case 0: do { *to = *from++;
  case 7: *to = *from++;
  case 6: *to = *from++;
  case 5: *to = *from++;
  case 4: *to = *from++;
  case 3: *to = *from++;
  case 2: *to = *from++;
  case 1: *to = *from++;
  } while (--n > 0);
} // Please do not write code like this..

Fibers example: Protothreads

// protothreads implementation: pt.h
define PT_BEGIN(pt) \
  switch(pt->lc) { case 0:

// … more macros defined …
define PT_WAIT_UNTIL(pt, c) \
  pt->lc = __LINE__; case __LINE__: \
  if(!(c)) return 0

include "pt.h"
// … protothreads example …
PT_THREAD(example(struct pt *pt)) {
  PT_BEGIN(pt);
  while (1) {
    if (initiate_io()) {
      timer_start(&timer);
      PT_WAIT_UNTIL(pt,
      io_completed() ||
      timer_expired(&timer));
      read_data();
    }
  }
}

Processes vs. threads. vs. fibers

Processes Threads Fibers
Address space separate common common
Kernel visibility yes yes no
Scheduling kernel level kernel level user space
Stack separate per process separate per thread can be common
Switching overhead very high high low

Conclusion