Computer Science 354
Operating Systems

Dickinson College
Spring Semester 2000
Grant Braught

/* * terror.c * Example program that demonstrates * critical sections and the existence * of a race condition. * * Compile with: * cc terror.c -o terror -lpthread -lm * * Grant Braught * Dickinson College * (c) 2000 */ #define _REENTRANT #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <math.h> #include <pthread.h> void *Thread_Func1(void *); void *Thread_Func2(void *); // Define some global variables that the threads will use. int Global_Var; double Global_Var2 = 7.6789; double Global_Var3 = 3.21234; double Global_Var4 = 7.6789; double Global_Var5 = 3.21234; int main() { pthread_t tid1, tid2; void *arg; int i; printf("\nterror.c\n\n"); printf("Demonstrate the thread synchronization problem.\n"); printf("Create 2 threads:\n"); printf("\tOne adds 1 to a global variable 10,000 times.\n"); printf("\tOne subtracts 1 from the same globla variable 10,000 times.\n"); printf("The process is repeated 40 times to increase the likelyhood\n"); printf("of seeing an error.\n"); printf("If the threads are synchronized the value should always\n"); printf("be zero. However, that is not the case...\n\n"); printf("Global Variable Values\n"); printf("-----------------------------------------------------------------------\n"); for (i=1; i<=40; i++) { // Initialize the global variable. Global_Var = 0; // Create the two threads... pthread_create(&tid1, NULL, Thread_Func1, arg); pthread_create(&tid2, NULL, Thread_Func2, arg); // Wait for the threads to finish... pthread_join(tid1,NULL); pthread_join(tid2,NULL); // Write out the value of the global variable. printf("%d\t\t",Global_Var); if (i % 5 == 0) printf("\n"); } } void *Thread_Func1(void *junk) { int i; // Each thread will do the addition or subtraction 10,000 times. // This is done because it is very unlikely that the thread will // be interrupted at a point where an error will be created. // However, it is not impossible. Therefore, repeating the instr. // lots of times will increase the likelyhood of seeing an error. // The pow instructions are included to make the addition and // subtraction operations take more time. This increases the // likelyhood of a thread being interrupted. for (i=1; i<=10000; i++) { Global_Var = Global_Var + (int) pow(Global_Var2,Global_Var3) - (int) pow(Global_Var4,Global_Var5) + (int) pow(Global_Var3,Global_Var2) - (int) pow(Global_Var5,Global_Var4) + 1; } } void *Thread_Func2(void *junk) { int i; for (i=1; i<=10000; i++) { Global_Var = Global_Var + (int) pow(Global_Var2,Global_Var3) - (int) pow(Global_Var4,Global_Var5) + (int) pow(Global_Var3,Global_Var2) - (int) pow(Global_Var5,Global_Var4) - 1; } }