Synchronisation Problems

These are the famous synchronisation problems which are used to prevent, either the same piece of code or a variable being accessed by multiple programmes at a time ( critical section problem )

All the programmes below are in "C" and use file handling.There will be sub headings related to the  synchronisation problems and below them the corresponding code snippets.The code needs some input to be given, it would be obvious from the context if your know the problem well.Tested for DevCPP and codeblocks in Windows.If you have doubts, comment, will clarify them, with in at max two days.


1.Producer-Consumer Problem

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<semaphore.h>
#define SIZE 5
typedef int buffer_item;
sem_t mutex;//semaphore mutex lock declaration
sem_init(&mutex,0,1);//Getting default attributes to mutex
int empty=0;
int full=1;
int HEAD=-1;
int TAIL=-1;
buffer_item Buffer[SIZE];
//Wait function
void wait(int flag)
{
     if(flag==0)
     {while((HEAD+1)%SIZE==TAIL)
     sleep(2);}
     else
     {while(HEAD==-1 && TAIL==-1)
     sleep(2);
     }
     }
     //Signal function
void signal(int flag)
{
     if(flag==0)
     {
                 if(HEAD==TAIL)
           {HEAD=-1;
           TAIL=-1;
           }
                      else
           TAIL=(TAIL+1)%SIZE;
                }
                else
                {
                    HEAD=(HEAD+1)%SIZE;
                       if(TAIL==-1)
      TAIL=0;
                   }

     }

     //Inserting item function for Producer thread
int insert_item(buffer_item item)
{wait(empty);
sem_wait(&mutex);
//Critical section start

Buffer[((HEAD+1)%SIZE)]=item;

      //Critical section end
      sem_post(&mutex);
      signal(full);
}
//Removing or consuming item function for consumer thread
int remove_item()
{buffer_item temp;
    wait(full);
sem_wait(&mutex);
//Critical section start
temp=Buffer[TAIL];
//Critical section end
sem_post(&mutex);
      signal(empty);
      return temp;
      }
      //Thread for Producer process
    void *producer(void *param)
    {
         buffer_item item;
         item=rand();
         insert_item(item);
         printf("Item - %d successfully produced",item);
         }
         //Thread for consumer process
    void *consumer(void *param)
    {
         buffer_item temp;
         temp=remove_item();
         printf("The item consumed successfully is %d",temp);
         }
int main()
{int i,j;
    pthread_t tid1[5],tid2[5];//Thread id's
pthread_attr_t attr;//Thread attributes
pthread_attr_init(&attr);//Setting thread attributes to their default value
printf("Enter the number of producer and consumer processes you want:");
scanf("%d%d",&i,&j);
while(i)
{pthread_create(&tid1[i],&attr,producer,i);
i--;
}
while(j)
{pthread_create(&tid2[j],&attr,consumer,i);
j--;
}
sleep(60);
}

2.Reader-Writer Starvation Free Solution

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
int mutex[3],wrt,rd,flag;//semaphore mutex lock declaration
int readercount,writercount;
int read[6][2],write[6][2];
int p(int *mutex)
{
 while(*mutex==0)
 sleep(2);
 *mutex=0;   
    }
int v(int *mutex)
{
    *mutex=1;
}
//Wait function
int readerwriterlockwait(char *mode)
{
                           if(mode=="write")
                           {p(&flag);
                                            p(&mutex[0]);//To make the below atomic and exclusive
                           writercount++;
                           if(writercount==1)//If first writer, then there is a need to check if any one is reading
                           p(&rd);
                           v(&mutex[0]);
                             p(&wrt);//Write lock, so that when one is modifying, the other cannot touch it
                                                 }
                           else
                          { p(&flag);
                               p(&mutex[1]);//To make the below atomic and exclusive
                               p(&rd);//Read lock to show that some one has started reading
                               p(&mutex[2]);//To make the below atomic and exclusive and also to avoid signal of other read to modify readercount at the same time
                               readercount++;
                               if(readercount==1)//If he is a first reader, he must make sure that no one is modifying or writing
                               p(&wrt);
                               v(&mutex[2]);
                               v(&rd);//Lock is removed before the reading process has begun because two readers can read at the same time
                               v(&mutex[1]);
                               v(&flag);
                               }
                                                     }
//Signal function    
int readerwriterlocksignal(char *mode)
{
                             if(mode=="write")
                         { v(&wrt);//Writing lock is removed
                          v(&flag);
                             p(&mutex[0]);//To make the below ones atomic and exclusive
                          writercount--;
                          if(writercount==0)
                          v(&rd);//Reading lock is removed, now any one can read since no writer is modifying
                          v(&mutex[0]);
                                                    }
                             else
                        {p(&mutex[2]);
                          readercount--;
                        if(readercount==0)
                        v(&wrt);
                        v(&mutex[2]);
                                             }
                        
}

//Reader thread
DWORD WINAPI Reader(LPVOID *Param)
{DWORD i=*(DWORD *)Param;
char *mode;
//Not arrived
sleep(read[i][0]*1000);
//Arrived
      mode="read";
     readerwriterlockwait(mode);
          //Reads the item
     sleep(read[i][1]*1000);
     //Completed reading
     readerwriterlocksignal(mode);
     printf(" Reader-%d has completed reading\n",i+1);
          
     }
     //Writer thread
DWORD WINAPI Writer(LPVOID *Param)
{char *mode;
      DWORD i=*(DWORD *)Param;
      //Not arrived
      sleep(write[i][0]*1000);
      //Arrived
      mode="write";
readerwriterlockwait(mode);
//Modifies an item
     sleep(write[i][1]*1000);
//Completed modifying
readerwriterlocksignal(mode);
 printf(" Writer-%d has completed modifying\n",i+1);
}
int main()
{readercount=0;
writercount=0;

flag=1;
mutex[0]=1;
mutex[1]=1;
mutex[2]=1;
wrt=1;
rd=1;
int l;
int Param[6];
  DWORD ThreadId[6];
int i,j;
int readcount,writecount;
//Reader input start
printf("Enter the number of readers:");
scanf("%d",&readcount);
printf("Enter the arrival time and reading time of %d readers\n",readcount);
for(i=0;i<readcount;i++)
for(j=0;j<2;j++)
scanf("%d",&read[i][j]);
//Reader input end
//Writer input start
printf("Enter the number of writers:");
scanf("%d",&writecount);
printf("Enter the arrival time and writing time of %d writers\n",writecount);
for(i=0;i<writecount;i++)
for(j=0;j<2;j++)
scanf("%d",&write[i][j]);
//Writer input end
 HANDLE ThreadHandleReader[6];
     l=readcount-1;
    while(l!=-1)
    {Param[l]=l;
    ThreadHandleReader[l]=CreateThread(NULL,0,Reader,&Param[l],0,&ThreadId[l]);
    l--;
}
 HANDLE ThreadHandleWriter[6];
    l=writecount-1;
    while(l!=-1)
    {Param[l]=l;
    ThreadHandleWriter[l]=CreateThread(NULL,0,Writer,&Param[l],0,&ThreadId[l]);
    l--;
}
getche();   
}

3.Dining Philosopher Problem


#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<windows.h>
int Chopstick[5];//Each chopstick is a semaphore
//If chopstick=1, the chopstick is free, otherwise someone grabbed it
int l;
int TE[5][2];//For storing the eating and thinking time of philosophers

Wait(int i)
{
      while(1)
      {while(Chopstick[i]==0)//He goes on checking for left chopstick
      sleep(2);
      Chopstick[i]=0;//Immediately grabs the left chopstick
   
      if(Chopstick[(i+1)%5]==0)//If right chopstick found he breaks
      break;
      Chopstick[i]=1;//Otherwise he will release the left chopstick and again goes back
      sleep(2);
      }
      Chopstick[(i+1)%5]=0; //Right chopstick is also grabbed
            }
Signal(int i)
{Chopstick[i]=1;
Chopstick[(i+1)%5]=1;
}
DWORD WINAPI Eat(LPVOID *Param)
{DWORD i=*Param;
sleep(TE[i][0]*1000);//Thinking
Wait(i);
sleep(TE[i][1]*1000);//Eating
Signal(i);
printf("Philosopher %d has completed eating\n",*(DWORD*)Param+1);
return 0;}
int main()
{int i,j;
    l=4;
    while(l!=-1)
{Chopstick[l]=1;
l--;}
printf("Enter the values of thinking and eating for five philosophers:\n");
for(i=0;i<5;i++)
for(j=0;j<2;j++)
scanf("%d",&TE[i][j]);
    HANDLE ThreadHandle[5];
    DWORD ThreadId[5];
    int Param[5];
    l=4;
    while(l!=-1)
    {Param[l]=l;
    ThreadHandle[l]=CreateThread(NULL,0,Eat,&Param[l],0,&ThreadId[l]);
    l--;
}
getche();
         return 0;}




3 comments: