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 #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 #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: