Sistemas Operativos 3MIEEC

Problem Set #5: POSIX Mutexes


Questions

  1. Consider the following C code snipet:
    	1: tmp = n;
    	2: tmp++;
    	3: n = tmp;	
    where both n and tmp are integer variables.

    Show, by means of a sequence of instructions (interleaving) how the concurrent execution of this code by 2 threads can lead to a race condition. Assume that each of these C instructions is atomic.

  2. Assume that instead of this 3 instructions sequence we use a single instruction:
    	1: n++;	
    1. Can it lead to a race condition when executed by more than one thread and variable n is implemented in memory? Justify
    2. What if n is implemented in a processor register? Is there a race condition? Justify.

Problems

Note To compile thread-based programs you must use the -pthread compiler option. This ensures linking with the libpthread library and with the thread-safe functions of the C library.

IMP. Follow an incremental code development approach. If you write all the code in a single go and only then compile it, you risk spending the following 15 minutes eliminating the compilation errors and the remaining class debugging it. Instead, you should add code step by step, compiling it and testing it, after each step.

  1. In this problem you will write a very simple multi-threaded program that increments a shared counter.
    1. The program's main thread creates 3 other threads.

      Each ot these 3 threads shall increment a shared counter (long int) a number of times, specified as a command line argument to the program.

      The main thread shall wait for the termination of the other 3 threads, and then shall print the final value of the counter.

      Compile your program and run it several times. Explain the observed results.

    2. Write a new version of the previous program, keeping the same global structure, thread number and duties per thread, but now using mutexes/locks for thread synchronization in the access to the shared counter.

      Try to maximize the concurrency among the different threads.

      Compile your program and run it several times. Explain the observed results.

  2. In this problem you will write a simple multi-threaded program that increments a shared counter.
    1. Write a program whose main thread creates 3 other threads.

      Each ot these threads (different from the main thread) shall execute the tfun() function to increment a variable defined in main() the number of times passed as a command line argument to the program.

      The main thread shall wait for the termination of the other 3 threads, and then shall print the value of the counting variable.

      IMP. Read carefully tfun() to ensure that you specify correctly the last argument of pthread_create(). All threads must increment the same variable.

      Compile your program and run it several times. Explain the observed results.

    2. Write a new version of the previous program using mutexes/locks for thread synchronization. Try to maximize the concurrency among the different threads.

      Hint: Write a new version of tfun() that you should name sfun() (s from synchronized)

      Compile your program and run it several times. Explain the observed results.

  3. In this problem you will develop a thread-safe stack as a linked data structure.
    1. Write the code for a stack in an object oriented way. (All functions of the stack should be in implemented in its own C source file. Furthermore, you should write an header file with the interface provided by your stack.) Each stack element shall have the following type (which should be included in the header file):

      	struct stack_el{
      		char *str;              /* String to be printed in show() */
      		int n;                  /* Integer to be printed in show() */
      		struct stack_el *next;  /* Link to next stack element */
      	};
      	

      Your stack shall provide the standard push() and pop() functions, and also a show() function, which lists all elements in the stack from top to the bottom.

    2. Write a small (single-threaded) test program using the functions you have developed.

    3. Write a new multi-threaded program to show race conditions when multiple threads try to access a shared stack.

    4. Write a thread safe version of your stack abstract data type using mutexes. Programs that use your thread safe version of the stack, should not have to invoke explicitly any synchronization primitives. Test it using the multi-threade program you have developed in the previous exercise.

  4. In this problem you should solve all questions but the last of the programming test of 2012/2013 (use this link for the English version).
  5. In this problem you should solve all questions but the last of the programming test of 2010/2011.