Lecture Notes for Client-Server Interfaces

15 February 2001 - Server Concurrency with Unix fork()


  1. create a new computation for every new request

    1. forks are expensive - requests should be too

  2. architecture

    1. listener <- socket()
      bind(listener)
      listen(listener)
      loop {
        active <- accept()
        if (fork())
          close(active)
        else
          close(listener)
          loop
            write(active, f(read(active)))
          exit()
        }
      

    2. fork() only

    3. datagram too, but f() should be expensive

  3. The fine points

    1. process termination

      1. a parent should acknowledge when a child exits

      2. the many wait() system calls acknowledge child exits

      3. a parent receives a sigchld signal on each child exit - the signal() system call

      4. either block in a wait() or call wait() from within the sigchld signal handler

    2. interrupted system calls

      1. the parent's going to be blocked inside the accept()

      2. the error return's EINTR - need to check that separately

      3. do active <- accept()
        while active != EINTR
        


This page last modified on 2 March 2001.