CS 111 Operating System (Fall 2014)

Lecture 6 Scribe Note

prepared by Meixian Li for lecture presented by Paul Eggert on October 22th, 2014


Tabel of content

  1. What can go wrong?(Cont'd)
  2. Signals
  3. Threads

1. What can go wrong?(Cont'd)

  1. File Descriptors
    1. close(-1) or close(39)==-1, errno == EBADF
    2. fd = open(...) -> read(fd)... -> fd leak
    3. fd = open("/dev/usb/dr1",....) -> read(fd,...) -> unplug -> read(fd,...) -> return -1
  2. Race Condition: Behavior depends on timing (variable), hard to debug
    1. (cat a & cat b) > outfile
      img1
      possible outputs:
      • a\n -> output discard
      • b\n -> output discard
      • a\nb\n -> ok
      • b\na\n -> ok
      • ab\n\n -> not good
      • ...
      *notes:
      *if small "writes" <= 1024 bytes
      outputs of single writes are done atomically
      *if large "writes"
      outputs of single write are syscall interleaved
    2. (cat > a & cat > b) < infile
      img2
      |a| + |b| = |infile|

2. Singals

  1. Task: Rotate a log file
    Suppose we have two log files:
    a. Log
    -Today's log, apache writes to this (keep growing)
    b.Oldlog
    -Yesterday's log (no change)
    At every midnight, we move yesterday's log to Oldlog, and write today's log to Log as follows:
    
    			$ mv log oldlog
    			$ > log
    			
    Problem:
    There is no log file during "mv" and "write", so apache can't start
    Solution
    
    		//piece of code for apache write to log
    		close(fd);
    		fd = open("log", O_WRONLY);
    		checklog();
    		write(fd, "...", n);
    		checklog();
    		write(fd, "...", m);
    				
    		//checklog
    		void checklog(){
    		if(stat("log", &st) < 0 ||st.st_sid ==0){
    			close(fe);
    			fd=open("log",...);}
    		}
    			
    Evaluation of solution: using polling method, make it inefficient, and the solution is slow.

  2. Signals
    To avoid solving the above problem with polling, we can let kernel take control with signals. As kernel can
    terminate process, continue as before, and cause your program to call one of your functions, Which called
    "asynchronous/random" function call that could avoid polling.

    Signal Types:
    Example of sending signals: int kill(pid_t pid, int sig)
    
    		pid_t p = fork();
    		if(p>0){
    		   sleep(30);
    		   kill(p, SIGINT);
    		}
    		waitpid(p, NULL, 0);
    		
  3. Signal Handling


3. Threads

Like process, but lighter-weight.
pros:
performance
we want lots of them
we want fast context-switching(threads are not insulated from each other which means faster communication)
cons:
simplicity
reliability
Comparison between Treads and Process:
thread process
pthread_createfork
pthread_joinwaitpid
pthread_exit_exit