CSCI 3500: Studio 10

Race Conditions


Race conditions are a common problem of multi-threaded and parallel programming. Our goal today is to create a race condition and observe its behavior.

In this studio, you will:

  1. Create a shared global variable
  2. Access this variable from a single thread
  3. Access this variable from multiple threads
  4. Demonstrate a race under parallel execution (simultaneous execution)
  5. Demonstrate a race under sequential execution (concurrent execution)

Please complete the required exercises below, as well as any optional enrichment exercises that you wish to complete.

As you work through these exercises, please record your answers in a text file. When finished, submit your work by sending your text file and source code to dferry@slu.edu with the phrase Race Condition in the subject line.

Make sure that the name of each person who worked on these exercises is listed in the first answer, and make sure you number each of your responses so it is easy to match your responses with each exercise.


Required Exercises

  1. As the answer to the first exercise, list the names of the people who worked together on this studio.

  2. Create a new program, and create a global variable of type int and called race at the top of your program. Then write two functions, called adder and subtractor, which increment and decrement the variable race by two million times each. Copy and paste these functions.

  3. What do you think would happen if you executed these functions directly in main()? Test your hypothesis by doing so. What happens?

  4. What do you think will happen if these two functions were executed simultaneously by two different threads? What specific value do you think the variable race would have?

  5. Modify your program so that each function is executed by its own thread via pthread_create(). What is the result? Copy and paste several executions of your program.

  6. Can you explain the program's behavior? What do you think the maximum or minimum value could ever be?

  7. Try changing the number of iterations from two million to one million, and then from one million to 500,000. Does your program still exhibit this behavior? Try your program with 1000 iterations and try your program ten or fifteen times. What about now?

  8. Could your race condition still exhibit itself if your machine had only one processor core? Why or why not?

  9. We can simulate this by running your program and only allowing it to execute on one processor. Execute the command:

    taskset -c 0 ./race_program

    This restricts the program race_program to only execute on processor zero. What happens?

  10. Modify your program so that each function performs two hundred million operations (200,000,000). Run your program on one processor core, what happens?

  11. Give a reasonable explanation of the behavior in the previous exercise.

Optional Enrichment Exercises

  1. No optional exercises