Skip to main content

Linux & C :- Use of semaphores to solve race condition

Definition



A semaphore is a protected variable whose value can be accessed and altered only by the operations P and V and initialization operation called 'Semaphoiinitislize'.

Binary Semaphores can assume only the value 0 or the value 1 counting semaphores also called general semaphores can assume only nonnegative values.


The P (or wait or sleep or down) operation on semaphores S, written as P(S) or wait (S), operates as follows:

P(S):   IF   S  >  0
                 THEN  S :=  S - 1
                 ELSE   (wait on S)


The V (or signal or wakeup or up) operation on semaphore S, written as V(S) or signal (S), operates as follows:

V(S):   IF  (one or more process are waiting on S)
                THEN (let one of these processes proceed)
                ELSE   S := S +1


Operations P and V are done as single, indivisible, atomic action. It is guaranteed that once a semaphore operations has stared, no other process can access the semaphore until operation has completed. Mutual exclusion on the semaphore, S, is enforced within P(S) and V(S).

If several processes attempt a P(S) simultaneously, only process will be allowed to proceed. The other processes will be kept waiting, but the implementation of P and V guarantees that processes will not suffer indefinite postponement.

Semaphores solve the lost-wakeup problem.

Producer-Consumer Problem Using Semaphores

The Solution to producer-consumer problem uses three semaphores, namely, full, empty and mutex.

The semaphore 'full' is used for counting the number of slots in the buffer that are full. The 'empty' for counting the number of slots that are empty and semaphore 'mutex' to make sure that the producer and consumer do not access modifiable shared section of the buffer simultaneously.

Initialization

Set full buffer slots to 0.
    i.e., semaphore Full = 0.
Set empty buffer slots to N.
    i.e., semaphore empty = N.
For control access to critical section set mutex to 1.
    i.e., semaphore mutex = 1.
Producer ( ) 
WHILE (true)         
            produce-Item ( );
        P (empty);
        P (mutex);
        enter-Item ( )
        V (mutex)
        V (full);

Consumer ( )
WHILE (true) 
        P (full)
        P (mutex);
        remove-Item ( );
        V (mutex);
        V (empty);
        consume-Item (Item)

An Example:-

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

struct msgbuf {
               long mtype;       /* message type, must be > 0 */
               char mtext[10];    /* message data */
           };



union semun {
               int              val;    /* Value for SETVAL */
               struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
               unsigned short  *array;  /* Array for GETALL, SETALL */
               struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                           (Linux-specific) */
           };

struct buffer
{
 unsigned short sem_num;  /* semaphore number */
           short          sem_op;   /* semaphore operation */
           short          sem_flg;  /* operation flags */
};



int main(int argc, char* argv[])
{
struct msgbuf buf;
struct buffer buf1;
union semun sem;
int msg_id=msgget((key_t)2341,IPC_CREAT|IPC_EXCL);
if(msg_id<0)
{
printf("Already exists\n");
msg_id=msgget((key_t)2341,0666);
if(msg_id<0)
{
printf("handle error\n");
return 0;
}
}


////////////////////

int sem_id=semget((key_t)6001,1,IPC_CREAT|IPC_EXCL);

if(sem_id<0)
{
printf("already used semaphore\n");
sem_id=semget((key_t)6001,1,0666);
if(sem_id<0)
{
printf("error in getting semaphore\n");
return 0;
}
}
//sem.val=1;
//semctl(sem_id,0,SETVAL,sem);
sem.val=0;
semctl(sem_id,0,SETVAL,sem);

///////////////////////////


buf.mtype=atoi(argv[1]);
strcpy(buf.mtext,"test it");
int ret=msgsnd(msg_id,&buf,sizeof(buf.mtext),0);

if(ret<=0)
printf("msg sndng error%d\n",ret);

return 0;
}


Creating Reader 1


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

struct msgbuf {
               long mtype;       /* message type, must be > 0 */
               char mtext[10];    /* message data */
           };





union semun {
               int              val;    /* Value for SETVAL */
               struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
               unsigned short  *array;  /* Array for GETALL, SETALL */
               struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                           (Linux-specific) */
           };

struct buffer
{
 unsigned short sem_num;  /* semaphore number */
           short          sem_op;   /* semaphore operation */
           short          sem_flg;  /* operation flags */
};


int main()
{
struct buffer buf1;
union semun sem;

struct msgbuf buf;
int msg_id=msgget((key_t)2341,IPC_CREAT|IPC_EXCL);
if(msg_id<0)
{
printf("Already exists\n");
msg_id=msgget((key_t)2341,0666);
if(msg_id<0)
{
printf("handle error\n");
return 0;
}
}


int ret=msgrcv(msg_id,&buf,sizeof(buf.mtext),10,0);

if(ret<=0)
printf("msg sndng error\n");
else
printf("%s\n",buf.mtext);


int sem_id=semget((key_t)6001,1,IPC_CREAT|IPC_EXCL);

if(sem_id<0)
{
printf("already used semaphore\n");
sem_id=semget((key_t)6001,1,0666);
if(sem_id<0)
{
printf("error in getting semaphore\n");
return 0;
}
}
//sem.val=1;
//semctl(sem_id,0,SETVAL,sem);
buf1.sem_num=0;
buf1.sem_flg=SEM_UNDO;
buf1.sem_op=1;

semop(sem_id,&buf1,1);

return 0;
}


Creating Reader 2


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

struct msgbuf {
               long mtype;       /* message type, must be > 0 */
               char mtext[10];    /* message data */
           };



union semun {
               int              val;    /* Value for SETVAL */
               struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
               unsigned short  *array;  /* Array for GETALL, SETALL */
               struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                           (Linux-specific) */
           };

struct buffer
{
 unsigned short sem_num;  /* semaphore number */
           short          sem_op;   /* semaphore operation */
           short          sem_flg;  /* operation flags */
};


int main()
{
struct msgbuf buf; //buffer for message queue
struct buffer buf1; //buffer for semaphore
union semun sem; //union for semaphore
int msg_id=msgget((key_t)2341,IPC_CREAT|IPC_EXCL);  //taking the message queue
int sem_id=semget((key_t)6001,1,IPC_CREAT|IPC_EXCL); //taking the semaphore

if(sem_id<0)
{
printf("already used semaphore\n");
sem_id=semget((key_t)6001,1,0666);
if(sem_id<0)
{
printf("error in getting semaphore\n");
return 0;
}
}
//sem.val=0;        //initialize the semaphore
//semctl(sem_id,0,SETVAL,sem);
buf1.sem_num=0;
buf1.sem_flg=SEM_UNDO;
buf1.sem_op=-1;  //wait operation

semop(sem_id,&buf1,1); //wait
if(msg_id<0)
{
printf("Already exists\n");
msg_id=msgget((key_t)2341,0666);
if(msg_id<0)
{
printf("handle error\n");
return 0;
}
}

int ret=msgrcv(msg_id,&buf,sizeof(buf.mtext),30,0);  //reading the MQ

if(ret<=0)
{
printf("msg sndng error\n");
}
else
{
printf("%s\n",buf.mtext);
msgctl(msg_id,IPC_RMID,NULL);  //removing the MQ
semctl(sem_id,0,IPC_RMID);     //removing the semaphore
}
return 0;
}


Comments

Popular posts from this blog

CDAC COURSES AND PLACEMENTS, WHICH IS BETTER FOR YOU

Click here to ask questions regarding CDAC
Before going through this post, I would like to draw your attention towards the importance of this post. This page not only explains my experience in CDAC but also aims at answering the queries of you all who are going or looking to have a course from CDAC. Kindly post your queries at the bottom of this page and we will get back to you within 24 hours. Kindly do not post your queries as an Anonymous user and do not forget to subscribe via email so as to keep track of your query.

                        click below to know about the CCAT's This batch allotment                 click below to know about the CCAT's This batch allotment ______________________________________________
NOW a day lot of the graduates and post graduates are wondering most of the times on which course they should go for. What are the pros & cons of joining a particular centre of CDAC. Here is a comprehensive information on how to enroll ourselves for a cour…

CDAC CCAT Rank - Which Centre you Should go for...

Click here to ask questions regarding CDAC
1. C-DAC (Head Quarters) Pune 
CDAC's Admission Booklet- Process of Admission to Post Graduate Diploma Courses of C-DAC                         click below to know about the CCAT's This batch allotment
               click above to know about the CCAT's This batch allotmentRank 1-300
c-dac HQ has been the best from the start.

2. Sunbeam Pune

Rank 300-500
I got very positive feedback from my friends who are in c-dac banglure main campus,since there are many companies you may get more opportunities.

3. C-DAC Knowledge Park

Rank 400-700
It as very good faculty .Almost all the students get placed here every year.

4. C-DAC Hyderabad

Rank 200-1000 (It depends on the course which you select)
C-DAC hyderabad is very good for the course PG-DESD.
PG-DESD course is in hyderbad is better than pune HQ as per the past feedback.It as very good placement record in hyd for PG-DESD course.Rank for PG-DESD is 1-300.
PG-DAC as no good placement record from few yea…

Placement Statistics - 2011 & 2012

Post your queries below and we will get back to you in no more than 24 hours.  Click here to ask questions regarding CDAC                         click below to know about the CCAT's This batch allotment                     click above to know about the CCAT's This batch allotment
CDAC's Admission Booklet- Process of Admission to Post Graduate Diploma Courses of C-DAC

Click here to see placement statistics

About C-CAT, Exam Pattern and Books

No. of Seats Across Various Training Centres

Important Dates - 2014








Tags: CDAC, CDAC scope in future, CDAC placements, CDAC training, CDAC recruitment, CDAC training centres, DSSD, DESD, DAC, PGDSSD, PGDESD, PGDAC, DABC, PGDABC, VLSI, PGDITISS, PGDIVESD, PGDESD, PGDWiMC, placement statistics