Another example of mutual exclusion


process-1.c and process-2.c are two processes need to display their outputs on the standard output. To ensure the output is right, these two processes should access the standard output exclusively. That is to say, process should wait until the other process that occupies the standard output finishes its display. Otherwise, the output may be confused as figure 1. We use semaphore to ensure mutual exclusion. The result is shown in figure 2.

Comment out semaphore related codes, run these two programs(proc-1.c,proc-2.c) and see what happens.

Figure 1. Confused result
Figure 2. Correct result

Compile and run like this:

$ gcc process-1.c -pthread -o process-1
$ gcc process-2.c -pthread -o process-2
$ ./process-1 & ./process-2 &
/*process-1.c*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
int main(int argc, char * argv[]) {
       sem_t * mutex;
       char * c = "This is CSCI3150--An operating system course.\n";
    // specify no buffering for stderr
    setbuf(stderr, NULL);
       mutex = sem_open("mutex_for_stderr", O_CREAT, 0666, 1);
       sem_wait(mutex);
       while (* c != '\0') {
            fputc(* c, stderr);
            c++;
            sleep(1);
         }
    sem_post(mutex);
    sem_close(mutex);
    sem_unlink("mutex_for_stderr");
    return 0;
}

/*process-2.c*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
int main(int argc, char * argv[]) {
    sem_t * mutex;
    char * c = "This is CSCI3150--An operating system course.\n";
    // specify no buffering for stderr
    setbuf(stderr, NULL);  
    mutex = sem_open("mutex_for_stderr", O_CREAT, 0666, 1);
    sem_wait(mutex);
    while (* c != '\0') {
        fputc(* c, stderr);
        c++;
        sleep(rand()%2+1);
    }
    sem_post(mutex);
    sem_close(mutex);
    sem_unlink("mutex_for_stderr");
    return 0;
}