You are on page 1of 22

Semaphores

• Dijkstra (1965) introduced the concept of a semaphore


• Semaphores are variables that are used to signal the status of shared resources
to processes (a semaphore could have the value of 0, indicating that no
wakeups are saved, or some positive value if one or more wakeups are
pending)
• the down operation on a semaphore
o checks to see if the value is greater than 0
o all is done as a single, indivisible atomic action
 checking the value
 changing it
 possibly going to sleep
• the up operation on a semaphore
o increments the value of the semaphore
o indivisible process; incrementing the semaphore and waking up one
process
• Solving the producer-consumer problem using semaphores (see Fig. 2.12)
• Possible uses of semaphores;
o Mutual exclusion, initialize the semaphore to one
o Synchronization of cooperating processes (signaling), initialize the
semaphore to zero
o Managing multiple instances of a resource, initialize the semaphore to
the number of instances
• Type of semaphores;
o binary
o counting
The producer-consumer problem using semaphore
1. WRITE A PROGRAM TO SHARE THE DATE BETWEEN PROCESSES
USING FILES
#include<fcntl.h>
#include<stdio.h>
main()
{
int fp;
char chr=’A’;
int pid;
pid=fork();
if (pid==0)
{
fp=open(“baby”,O_WRONLY,0666);
printf(“ In child chr is %c\n”,chr);
chr=’B’;
write(fp,&chr,1);
printf(“ In child chr after change %c\n”,chr);
printf(“child exiting\n”);
close(fp);
}
else
{
wait((int*)0);
fp=open(“baby”,O_RDONLY);
read(fp,&chr,1);
printf(“ chr after parent reads is %c”,chr);
close(fp);
}
}
2. By Creating child process send the result of command to child process.
main()
{
int pid;
pid=fork();
if ( pid==0)
{
printf(“ exec starts\n”);
execl(“/bin/ls”,”ls”,”-l”,(char*)0);
printf(“ Execl did not work\n”);
}
else
{
wait(0);
printf(“ Parent : ls is completed in child \n”);
}
}
3.write a program for every 10 seconds tell the number of users logged in .

main()
{
int pid;
pid=fork();
if (pid==0)
{
for(;;)
{
sleep(10);
printf(“ the number of users logged in are :”);
system(“who | wc –l”);
}
}
}
4. write a program by giving the name of the user and program will report you as
soon as he login.

#include<sys/types.h>
#include<stdio.h>
#include<utmp.h>
#define UTMP “/etc/utmp”

main(argc,argv)
int argc;
char * argv[];
{
FILE *fp;
struct utmp u;
for(;;)
{
fp=fopen(utmp,”r”);
while(!feof(fp))
{
fread(&u,sizeof(u),1,fp);
if (u.ut_name==NULL)
continue;
if(strcmp(argv[1],u.ut_name)==0)
{

printf(“\n\7\7\7 %s has login \n”,argv[1]);


exit(0);
}
}

fclose(fp);
sleep(5);
}
}

5. write a program to create a child process. Send the command to child process and
execute there and return the result to the parent by using IPC using pipes.
PARENT PROCESS CHILD PROCESS

Write
Read
(ls –il)
( sort )

PIPE

main()
{
char *one[3],*two[2];
int ret;
one[0]=”ls”;
one[1]=”-il”;
one[2]=(char*)0;

two[0]=”sort”;
two[1]=(char*)0;

ret=join(one,two);
printf(“ join returned %d\n”,ret);
exit(0);
}

int join (com1,com2)


char *com1[],*com2[]
{
int p[2],status;
switch(fork())
{

case -1:
perror(“error”);
case 0:
break;
default:
wait(&status);
return (status);
}
if (pipe(p) < 0)
perror(“pipe call in join “);
switch(fork())
{
case -1:
perror(“ 2nd fork call in join “);
case 0:
close(1);
dup(p[1]);
close(p[0]);
close(p[1]);
execl(“/bin/ls”,com1[0],com1[1],com1[2]);
perror(“ 1st execvp call in join”);
default:
close(0);
dup(p[0]);
close(p[0]);
close(p[1]);
execl(“/bin/sort”,com2[0],com2[1]);
perror(“2nd execvp call in join”);
}
}

6. Write a program to establish the message communication between the child and
parent process using pipes.
#include<stdio.h>
main()
{
int pp[2],pc[2],j,pid;
char msg1[20];
char msg2[20];
char msg3[20];
pipe(pp);
pipe(pc);
pid=fork();
if (pid==0)
{
close(pp[1]);
close(pc[0]);
write(pc[1],”hello daddy”,12);
read (pp[0],msg2,12);
printf(“%s\n”,msg2);
write(pc[1],”Thank you papa”,14);
}
else
{
close(pp[0]);
close(pc[1]);
read(pc[0],msg1,12);
printf(“%s\n”,msg1);
write(pp[1],”hello baby”,12);
read(pc[0],msg3,14);
printf(“%s\n”,msg3);
}
}

7. write a program for producer and cosumers problem..


Shared Memory

Shared memory is the second of the three IPC facilities. It allows two unrelated
processes to access the same logical memory.

Overview

Shared memory is a special range of addresses that is created by IPC for one process
and appears in the address space of that process.

Other processes can then 'attach' the same shared memory segment into their own
address space.

Try It Out - Shared Memory

1. Our first program is a coonsumer. After the header, a suitable MEM_SZ and a
structure have been defined.
5. Our second program, shm2.c, is the producer and allows us to enter data for
consumers.
When we run these programs, we get some sample output such as this:

How It works

The first program, shm1, crates the shared memory segment and then attaches it to its
address space.

The second program, shm2, gets and attaches the same shared memory segment. It
get data and makes it available to the other program.

Shared Memory Summary

Shared memory provides an efficient way of sharing and passing data between
multiple processes.

Message Queues

We'll now take a look at the third and final IPC facility: message queues.

Overview

Message queues provide a way of sending a block of data from one process to
another.

Message Queue Functions

The message queue function definitions are:


msgget

We create and access a message queue using the msg get function:

msgsnd

The msgsnd function allows us to add a message to a message queue.

When you're using messages, it's best to define your message structure something like
this:

msgrcv

The msgrcv function retrieves messages from a message queue.

msgctl

The msgctl is similar to the control function for shared memory.

The msqid_ds structure has at least the following members:


The first parameter, msqid, is the identifier returned from msgget.

The second parameter, command, is the action to take. This can take three values.

Try It Out - Message Queues


1. Here's the receiver program:
4. The sender program is very similar to msg1.c. We now have a call to msgsnd

to send the entered text to queue:


we'll run the sender, msg2, first. Here's some sample output:

How It Works

The sender program creates a message queue and adds messages to the queue. The
receiver gets the message queue id and receives messges until the special text end is
received.

the message:

You might also like