Sunday, September 14, 2014

Unix Prog: Race Condition

1. Race Condition

A race condition occurs when multiple processes are trying to do sth with shared data and the final outcome depends on the order in which the processes run.

In order to avoid the race condition, we need the signal mechanism to help process communication with each other.

2. Race Condition Example

proc.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
 #include<sys/wait.h>  
   
 void charatatime(char *str)  
 {  
  char *ptr;  
  int c;  
   
  setbuf(stdout, NULL);  
  for(ptr = str; (c=*ptr++)!=0;)  
   putc(c, stdout);  
 }  
   
 int main(int argc, char* argv[])  
 {  
  pid_t pid;  
   
  if((pid = fork()) < 0) {  
   printf("fork error!\n");  
   exit(1);  
  }  
  else if (pid == 0) {  
   int i;  
   for(i=0; i<10000; i++)  
    charatatime("output from a child!\n");  
  } else {  
   int i;  
   for(i=0; i<10000;i++)  
    charatatime("output from a parent!\n");  
  }  
   
  exit(0);  
 }  

shell:
Because we let parent process and child process output at the same time without setting any buffer. So we can see its output getting content missed up.
 ubuntu@ip-172-31-23-227:~$ ./proc.out >output.txt  
 ubuntu@ip-172-31-23-227:~$ grep -v "output from" output.txt  
 ouild!  
 out a child!  
  child!  
 ouparent!  
 ......  

3. Remove Race Condition Example

proc.c:
The only difference is: the parent process wait for child process finish firstly before outputting.
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
 #include<sys/wait.h>  
   
 void charatatime(char *str)  
 {  
  char *ptr;  
  int c;  
   
  setbuf(stdout, NULL);  
  for(ptr = str; (c=*ptr++)!=0;)  
   putc(c, stdout);  
 }  
   
 int main(int argc, char* argv[])  
 {  
  pid_t pid;  
   
  if((pid = fork()) < 0) {  
   printf("fork error!\n");  
   exit(1);  
  }  
  else if (pid == 0) {  
   int i;  
   for(i=0; i<10000; i++)  
    charatatime("output from a child!\n");  
  } else {  
   // Before parent process do sth, wait for child finish firstly  
   if(wait(NULL) < 0) {  
    printf("wait error!\n");  
    exit(2);  
   }  
   int i;  
   for(i=0; i<10000;i++)  
    charatatime("output from a parent!\n");  
  }  
   
  exit(0);  
 }  

shell:
 ubuntu@ip-172-31-23-227:~$ ./proc.out > output.txt  
 ubuntu@ip-172-31-23-227:~$ grep -v "output from" output.txt  
 ubuntu@ip-172-31-23-227:~$  

No comments:

Post a Comment