• web pages for usp and its programs
  • exercise 1: Compiling C programs
    • Your have to write four files, a makefile, two c programs and a c header file. (Refer to A.3)
    • The mylib.c should implement a function named reverse() which prototype is put in myinc.h and the prototype is:
      void reverse(char *s);
    • The main() in my.c should call the reverse() on each argument and print them out.
    • For example:
      $ make
      gcc    -c -o my.o my.c
      gcc    -c -o mylib.o mylib.c
      gcc -o my my.o mylib.o
      $
      $ ./my Klim is milK
      milK
      si
      Klim
      $ 
      
    • Due: 2011/Mar/10, 23:59
      You have to put your files under ~/usp-992/exer1.
    • For your reference, a program which shows the arguments is provided.
  • exercise 2: env utility
    • Refer to 2.12.
    • Due: 2011/Mar/31, 23:59
    • For example:
      $ ./a.out                                     # just like env
      CPLUS_INCLUDE_PATH=/usr/lib/qt/include
      ........
      JAVA_HOME=/usr/lib/java
      XMODIFIERS=@im=gcin
      $ ./a.out -i                               # ignore, so an empty environ
      $ ./a.out -i env                           # use an empty environ to run `env'
      PWD=/home/klim/tmp                         # system() will insert some env vars
      SHLVL=1
      _=/bin/env
      $ ./a.out env | grep JAVA_HOME                # the original envrion is copied
      JAVA_HOME=/usr/lib/java                       # and the JAVA_HOME has value ..
      $ ./a.out JAVA_HOME=ptt env | grep JAVA_HOME  # env is run with 
      JAVA_HOME=ptt                                 # modified environ
      $ ./a.out env | grep KLIM                     # no env var is named 'KLIM'
      $ ./a.out KLIM=milk env | grep KLIM           # Add an new env var.
      KLIM=milk                                     # Now here it is.
      $ 
               
  • exercise 3: practicing wait()
    • Refer to the exercise 2 of last year for explanation of the code .
    • Insert code to identify whether this process is a leaf or an internal node .
    • Remove the wait(NULL) in the loop. Instead, you have to insert certain wait() or sleep() after the printf() such that the processes will be not terminated too soon.
    • Open another window. You can kill a process with the command `kill'.
      For example, to kill a process which pid is 12011 with signal 15, you can type 'kill -15 12011'.
    • Once the process is killed, its parent can handle the exit status through the wait() code you have inserted after the sleep(). Refer to example 3.22.
    • If the process is a leaf, just sleep for a while so it can be killed by a signal which is sent by the user on another terminal.
      If the process is an internal node, wait for all children. For each child, when waited, report the signal number if it was terminated by a signal, or the value returned if it exited though exit(). In either case, a number is gained from the child. Those numbers from children are summed and the sum are used as the argument of exit(). This is to say the sum are the return value of this process.
    • Due: 2011/Apr/07, 23:59
    • For example:
      $ ./a.out ddduuduu abcd
      I'm c, my pid=3590, and my ppid=3589
      I'm b, my pid=3589, and my ppid=3588
      I'm d, my pid=3591, and my ppid=3588
      I'm a, my pid=3588, and my ppid=3295
      Child 3590 is terminated with signal 3.           $ kill -3 3590
      Child 3589 exits with value 3.
      Child 3591 is terminated with signal 2.           $ kill -2 3591
      $ echo $?                                # Check the return value of root.
      5                                        # It is the sum of 2 and 3.
      $ ./a.out ddduuduu abcd                  # Run it agagin.
      I'm c, my pid=3594, and my ppid=3593     # This time we try to kill the 
      I'm b, my pid=3593, and my ppid=3592     # internal node. The leaf node will
      I'm d, my pid=3595, and my ppid=3592     # be an orphan and be adopted by init.
      I'm a, my pid=3592, and my ppid=3295 
      Child 3593 is terminated with signal 4.           $ kill -4 3593
      Child 3595 is terminated with signal 15.          $ kill -15 3595
      $ echo $?
      19
      $ ps -ef | grep a.out                    # Find the orphan. Check its ppid.
      klim      3594     1  0 13:39 pts/0    00:00:00 ./a.out ddduuduu abcd
      klim      3597  3295  0 13:40 pts/0    00:00:00 grep a.out
      $ 
      
                
  • exercise 4: practicing pipe()
    • Build a process tree like the previous exercise, but two pipes are created between a parent and each one of its children. One pipe is for parent's sending to child, the other is for child's sending to the parent.
    • Each process will print a line, and the output will be printed on the screen in pre-order.
    • Due: 2011/Apr/28, 23:59
    • For example:
      $ ./a.out ddudduuduu abcde
      I'm a, my pid=4314, and my ppid=4234
      I'm b, my pid=4315, and my ppid=4314
      I'm c, my pid=4316, and my ppid=4314
      I'm d, my pid=4317, and my ppid=4316
      I'm e, my pid=4318, and my ppid=4314
      $ 
                
  • exercise 5: practicing random generator
    • When executed, you program will generate six processes, each emulating a random ball.
    • Two pipes should be created between each child and its parent. The purpose of pipes is for communication, just like the previous exercise.
    • The children processes are created once and serve many runs.
    • In each run, the parent generates a special number, and collects six other numbers from children. Of course, they should be different. The parent then prints them out.
    • Your program may run several runs and finally show the times of occurrence of each number.
    • Due: 2011/May/12, 23:59
    • Note: Each process should use a different seed.
    • For example:
      $ ./a.out 100000
      six balls:  7  4 10 21 47 32, special is 17
      six balls: 20 40  8 24 25  7, special is 6
      six balls: 42 12 27 24 45 15, special is 29
      six balls:  9 27 33 32 31 38, special is 7
      six balls: 10 17 22 38  5 24, special is 23
      six balls: 25 26 40 38 18 13, special is 10
      ................
      six balls: 15 21 35 29 19  6, special is 5
      six balls: 16 13 33 45 43 22, special is 5
      six balls: 32 35 13 14 46 31, special is 20
      Number  1 occurs 14203 times.
      Number  2 occurs 14356 times.
      Number  3 occurs 14099 times.
      Number  4 occurs 14231 times.
      Number  5 occurs 14236 times.
      Number  6 occurs 14347 times.
      Number  7 occurs 14199 times.
      Number  8 occurs 14272 times.
      Number  9 occurs 14321 times.
      Number 10 occurs 14282 times.
      Number 11 occurs 14442 times.
      Number 12 occurs 14302 times.
      Number 13 occurs 14297 times.
      Number 14 occurs 14421 times.
      Number 15 occurs 14246 times.
      Number 16 occurs 14074 times.
      Number 17 occurs 14313 times.
      Number 18 occurs 14025 times.
      Number 19 occurs 14237 times.
      Number 20 occurs 14182 times.
      Number 21 occurs 14271 times.
      Number 22 occurs 14308 times.
      Number 23 occurs 14054 times.
      Number 24 occurs 14263 times.
      Number 25 occurs 14385 times.
      Number 26 occurs 14351 times.
      Number 27 occurs 14216 times.
      Number 28 occurs 14295 times.
      Number 29 occurs 14120 times.
      Number 30 occurs 14463 times.
      Number 31 occurs 14163 times.
      Number 32 occurs 14492 times.
      Number 33 occurs 14357 times.
      Number 34 occurs 14260 times.
      Number 35 occurs 14474 times.
      Number 36 occurs 14355 times.
      Number 37 occurs 13980 times.
      Number 38 occurs 14417 times.
      Number 39 occurs 14366 times.
      Number 40 occurs 14425 times.
      Number 41 occurs 14303 times.
      Number 42 occurs 14530 times.
      Number 43 occurs 14242 times.
      Number 44 occurs 14378 times.
      Number 45 occurs 14281 times.
      Number 46 occurs 14218 times.
      Number 47 occurs 14397 times.
      Number 48 occurs 14102 times.
      Number 49 occurs 14449 times.
      $
                
  • exercise 6: poll() or select()
    • When invoked, your program will generate another six processes which form a ring linked with pipes. Refer to program 7.1.
      However, this exercise requires a bi-directional ring. It means each pair of adjoint prcoesses should be connected with two pipes. (Just like the previous exercise)
    • The root process will get input from a FIFO.
      When it gets a 'b', it will generate a random number and send it to the next clockwise child. The child, when received the number, will generate another random number and send all the numbers to the next child. The similar operations go on. Finally the root will get seven numbers from a child and print them out.
      When root gets a 'p', it will print its pid and send something to the anti-clockwise child. The child, when got the message, will also print its pid and send something to next child. And so on. Finally, the root reads something from a child and all processes have printed their pids.
    • The children processes should use poll() or select() to handle two input streams simultaneously.
    • If possible, you may design a protocol with which all the processes are terminated gracefully.
    • Due: 2011/May/19, 23:59
    • Note: Each process should use a different seed.
    • For example:
      =-=-=-=-=-=-=-=-=-=-=-=-=-=- first window =-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 
      $ mkfifo LOTTERY               <------ make a fifo
      $ ls -l LOTTERY                <------ check it
      prw-r--r-- 1 klim sys 0 2011-05-09 19:35 LOTTERY|
      $ \ls -l LOTTERY               <------ check it again but 'ls' is not aliased
      prw-r--r-- 1 klim sys 0 2011-05-09 19:35 LOTTERY
      $ ./a.out LOTTERY
      The six balls: 17 33 41 40 31 12, special is 48        <--- read a 'b'
      The six balls: 11 31  4 33 22  5, special is 21        <--- read a 'b'
      The six balls: 46 37  7 25 27  1, special is 19        <--- read a 'b'
      The six balls: 44 38 33 10 19 16, special is 41        <--- read a 'b'
      The six balls: 24 37 22 29 33 48, special is 8         <--- read a 'b'
      my pid is 3485                                         <--- read a 'p'
      my pid is 3491
      my pid is 3490
      my pid is 3489
      my pid is 3488
      my pid is 3487
      my pid is 3486
      The six balls: 29 34 13 27 35 31, special is 24       <----- read a 'b'
      The six balls: 41 32 38 19 22 43, special is 1        <----- read a 'b'
      The six balls: 24  3 18 45 19 36, special is 25       <----- read a 'b'
      The six balls: 47 44  8 36 34 39, special is 31       <----- read a 'b'
      The six balls: 37 47  1 49 18 35, special is 7        <----- read a 'b'
      my pid is 3485                                        <----- read a 'b'
      my pid is 3491
      my pid is 3490
      my pid is 3489
      my pid is 3488
      my pid is 3487
      my pid is 3486 
      $                     <---- got eof, try to terminate children gracefully.
      =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 
      
      =-=-=-=-=-=-=-=-=-=-=-=-=-=- second window =-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 
      $ cat > LOTTERY
      b
      b
      b
      b
      b
      p
      b
      b
      b
      b
      b
      p 
      $             <---------------------  type ^D, eof
      =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 
                
  • exercise 7: signal handling
    • Just like previous exercise, when invoked, your program will generate another six processes which, combined with the root, form a bi-directed ring linked with pipes.
    • Each process will handle two signals. When one of them, say SIGUSR1, arrives, it does the things for generating balls. (The same as the previous exercise)
      When another arrives, it does the things for showing pids. (The same as the previous exercise)
    • If possible, you may design a protocol with which all the processes are terminated gracefully.
    • Due: 2011/Jun/9, 23:59
    • Note: Each process should use a different seed.
    • For example:
                          SIGUSR1  ---  generate balls
                          SIGUSR2  ---  show pids
                          SIGINT   ---  terminate
      
                                   first window
      -----------------------------------------------------------------------------
      $ ./a.out 
      root pid is 4644
      my pid is 4650  <--------------------- kill -USR2 4644
      my pid is 4649
      my pid is 4648
      my pid is 4647
      my pid is 4646
      my pid is 4645
      my pid is 4644
      my pid is 4646  <--------------------- kill -USR2 4647
      my pid is 4645
      my pid is 4644
      my pid is 4650
      my pid is 4649
      my pid is 4648
      my pid is 4647
      The six balls: 40 25 19 26 10 46 special is 22, I'm 4646  <---- kill -USR1 4646
      The six balls: 43 18 37 27 33 47 special is 41, I'm 4650  <---- kill -USR1 ....
      The six balls: 44 30 26 21 47 20 special is 37, I'm 4646
      $                                                         <---- kill -INT  ....
      -----------------------------------------------------------------------------
      
      
                                   second window
      -----------------------------------------------------------------------------
      $
      $ kill -USR2 4644                    <----- show pids, Note that 4644 are the 
      $                                           last to show.
      $ kill -USR2 4647
      $
      $ kill -USR1 4646
      $
      $ kill -USR1 4646; kill -USR1 4650   <----- try to generate two sets of balls 
      $                                           concurrently
      $ kill -INT 4645                     <----- terminate 
      $ 
      -----------------------------------------------------------------------------