Synchronization primitives: Mutex and Semaphore (Sample Program) - Article 10

Hi Folks,

I have run this program on Intel I5 processor running Ubuntu Linux. You can imagine the speed and this program is a very tiny one. But still the output is garbled.

|3|The list is full
Count: 3
->|3|The list is full
|1|The list is full
->|7||3||3|->->The list is full
->|1||2|The list is full
->->|3||1|
->The list is full
The list is full
The list is full
|7|The list is full
|7|The list is full


The above is not expected output. You can see that list is not displayed properly. The synchronized version of program is shown below using Mutex variable by name pro(tection).

#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>

typedef struct node {
    struct node *link;
    int data;
} NODE;

static int count = 0;

NODE *head = NULL;

pthread_mutex_t pro;

NODE *get_node(void) {
    int data = rand();
    data = data % 13;
    NODE *ptr = (NODE *)malloc(sizeof(NODE));
    if(ptr != NULL) {
        ptr->data = data;
        ptr->link = NULL;
    }
    return ptr;
}

void print_node(NODE *ptr) {
    printf("|%d|",ptr->data);
    if(ptr->link != NULL) {
        printf("->");
    }
}

void display(void) {
    NODE *ptr = head;

    if(head == NULL) {
        printf("List is empty\n");
        return;
    }

    while(ptr != NULL) {
        print_node(ptr);
        ptr = ptr->link;
    }
    printf("\n");
}

void *producer(void *p) {
    NODE *temp;
    NODE *ptr;

    while(1) {
        pthread_mutex_lock(&pro);
        if(count >= 5) {
            printf("The list is full\n");
            pthread_mutex_unlock(&pro);
            continue;
        }
        temp = get_node();
        ptr = head;


        if(head == NULL) {
            head = temp;
            count++;
            printf("Count: %d\n",count);
            pthread_mutex_unlock(&pro);
            continue;
        }

        while(ptr->link != NULL)
            ptr = ptr->link;

        ptr->link = temp;
        count++;
        printf("Count: %d\n",count);
        display();
        pthread_mutex_unlock(&pro);
    }
}

void *consumer(void *p) {
    NODE *temp;

    while(1) {
        pthread_mutex_lock(&pro);
        temp = head;
        if(head == NULL) {
            printf("Nothing to delete\n");
            printf("Count: %d\n",count);
            pthread_mutex_unlock(&pro);
            continue;
        }
        head = head->link;
        free(temp);
        count--;
        printf("Count: %d\n",count);
        display();
        pthread_mutex_unlock(&pro);
    }
}

void main() {
    pthread_t tid1[10], tid2;
    int i;
    pthread_mutex_init(&pro, NULL);
    pthread_create(&tid2, NULL, consumer, NULL);
    for(i = 0;i < 10;i++)
        pthread_create(&tid1[i], NULL, producer, NULL);   
    for(i = 0;i < 10;i++)
        pthread_join(tid1[i], NULL);
    pthread_join(tid2, NULL);
}


The output is as below after synchronization:

Nothing to delete
Count: 0
Count: 1
Count: 2
|3|->|3|
Count: 3
|3|->|3|->|5|
Count: 4
|3|->|3|->|5|->|2|
Count: 5
|3|->|3|->|5|->|2|->|3|
The list is full
The list is full
The list is full


In the coming articles, we shall explore System V semaphores and conditional variables. We shall also summarize the differences between Mutex and Semaphore.

Comments

Popular posts from this blog

Synchronization primitives: Mutex and Semaphore (Serialization & Mutex problems using Semaphore) - Article 6

Synchronization primitives: Mutex and Semaphore (Readers & Writers problem) - Article 8

Copy constructor in C++ (Part 2)