0% found this document useful (0 votes)
13 views

Lect 07

Uploaded by

venkatagopinath4
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views

Lect 07

Uploaded by

venkatagopinath4
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 34

CSCI7645 - Systems Programming

Lecture 7: Semaphores
Instructor:Yongming Tang, Ph. D.
School of Computer Sciences and Engineering
Fairleigh Dickinson University
Semaphores
• Introduction
– A semaphore is a data structure that is shared
by several processes.
– Semaphores are most often used to synchronize
operations when multiple processes access a
common, non-shareable resource.
– Usually semaphores are used to avoid
starvation and deadlock.

11/08/24 Dr. Tang, FDU 2


Semaphores
• Introduction
– Starvation occurs when a process is continually
denied access to a resource it needs.
– Deadlock occurs when two or more processes
each hold a resource that the other needs while
waiting for the other process to release its
resource.
– When used to synchronize the access to a
resource, a semaphore is initially set to the
number of available resources.

11/08/24 Dr. Tang, FDU 3


Semaphores
• Introduction
– A positive, non-zero semaphore value indicates
the resource is available. On the other hand,
value zero means not available and the
requesting process must wait.
– To indicate it has gained access to the resource
the process decrements the semaphore.
– When a process is finished with a semaphore-
associated resource, the process indicates the
return of the resource by incrementing the
semaphore.

11/08/24 Dr. Tang, FDU 4


Semaphores
• Introduction
– Semaphores that control access to a single
resource, taking the value of 0 (resource is in
use) or 1 (resource is available), are often called
binary semaphores.
– Semaphores controlling access to multiple
resources, thus assuming a range of non-
negative values, are frequently called counting
semaphores.

11/08/24 Dr. Tang, FDU 5


Semaphores
• Introduction
– Implementation-wise, a semaphore is a non-
negative integer that is stored in the kernel.
– The semaphore system calls assure the user the test
and decrement operations on the semaphore will be
atomic.
– The semaphore system calls will, by default, cause
the invoking process to block if the semaphore
value indicates the resource is not available.
– When the resource becomes available, the
semaphore becomes non-zero, the system will
notify the queued, waiting, processes of this event.
11/08/24 Dr. Tang, FDU 6
Semaphores
• System Call semget() - signature

Include Files <sys/types.h> <sys/ipc.h> <sys/sem.h>


Summary int semget(key_t key, int nsems, int semflg);
Return Success Failure Sets errno
The semaphore id -1 Yes

11/08/24 Dr. Tang, FDU 7


Semaphores
• System Call semget() - arguments
– The 1st argument is used to generate a unique
semaphore identifier.
– The 2nd argument is the number of semaphores
in the set. The system will use the nsems value
when allocating the array of sem structures.
– The 3rd one, semflg, is used to specify access
permission and/or special creation conditions.
The flags IPC_CREAT and IPC_EXCL may be
ORed with the permission value.

11/08/24 Dr. Tang, FDU 8


Semaphores
• System Call semget() – specific values for key
– If the value for key is IPC_PRIVATE, or the value
for key does not have a semaphore identifier
associated with it, and IPC_CREAT has been
specified, a new set of semaphores is created.
– If IPC_CREAT is specified (but not IPC_EXCL)
and the semaphore set for the indicated key value
already exists, the semget system call will return
the associated semaphore identifier.

11/08/24 Dr. Tang, FDU 9


Semaphores
• System Call semget() - application
ipc_key = ftok(“.”, ‘S’);
if ((sem1 = semget(ipc_key, 3, IPC_CREAT | 0660)) == -1) {
perror(“semget: IPC_CREAT | 0660”);
}
printf(“sem1 identifier %d\n”, sem1);
if ((sem2 = semget(ipc_key, 3, IPC_CREAT| IPC_EXCL | 0660)) == -1) {
perror(“semget: IPC_CREAT|IPC_EXCL | 0660”);
}
printf(“sem2 identifier %d\n”, sem2);
if ((sem3 = semget(IPC_PRIVATE, 3, 0600)) == -1) {
perror(“semget: IPC_PRIVATE”);
}
printf(“sem3 identifier %d\n”, sem3);
11/08/24 Dr. Tang, FDU 10
Semaphores
• Program Example - Producer

#include <stdio.h> #include <sys/sem.h>


#include <unistd.h> #define PUB7645 "./PubFile"
#include <fcntl.h>
#include <stdlib.h> union semun {
#include <string.h> int val;
#include <sys/types.h> struct semid_ds *buf;
#include <sys/stat.h> ushort *array;
#include <sys/ipc.h> };

11/08/24 Dr. Tang, FDU 11


int
main() {
int i=0, intValue, semID;
key_t key;
FILE *fptr;

union semun arg; //struct msgbuf value;


static ushort startVal[2] = {1, 0};
static struct sembuf acquire = {0, -1, SEM_UNDO},
release = {1, 1, SEM_UNDO};

11/08/24 Dr. Tang, FDU 12


key = ftok(".", 's');

if ((semID = semget(key, 2, IPC_CREAT | 0666)) == -1) {


perror("Sem Creation:");
exit(2);
}
arg.val=1;
if (semctl(semID, 0, SETVAL, arg) == -1 ) {
perror("semctl: SETALL");
exit(3);
}
arg.val=0;
if (semctl(semID, 1, SETVAL, arg) == -1 ) {
perror("semctl: SETALL");
exit(3);
}
/*arg.array = startVal;
if (semctl(semID, 2, SETALL, arg) == -1 ) {
perror("semctl: SETALL");
exit(3);
11/08/24 Dr. Tang, FDU 13
}*/
for( ; ; ) {
srand(getpid()+i);
intValue =random()*49/RAND_MAX + 1;

if (semop(semID, &acquire, 1) == -1) {


perror("Producer waiting");
exit(4);
}

if ((fptr = fopen(PUB7645, "w")) == NULL) {


perror(PUB7645);
exit(1);
}

11/08/24 Dr. Tang, FDU 14


fprintf(fptr, "%d\n", intValue);
fclose(fptr);

if (semop(semID, &release, 1) == -1) {


perror("new");
exit(5);
}
i++;
}
}

11/08/24 Dr. Tang, FDU 15


Semaphores
• Program Example - Consumer

#include <stdio.h> #include <sys/sem.h>


#include <unistd.h> #define PUB7645 "./PubFile"
#include <fcntl.h>
#include <stdlib.h> union semun {
#include <string.h> int val;
#include <sys/types.h> struct semid_ds *buf;
#include <sys/stat.h> ushort *array;
#include <sys/ipc.h> };

11/08/24 Dr. Tang, FDU 16


int main() {
int i=0, intValue, semID;
key_t key;
FILE *fptr;

union semun arg;


static struct sembuf acquire = {1, -1, SEM_UNDO},
release = {0, 1, SEM_UNDO};

key = ftok(".", 's');

if ((semID = semget(key, 2, IPC_CREAT | 0666)) == -1) {


perror("Sem Creation:");
exit(1);
}

11/08/24 Dr. Tang, FDU 17


for(i=1; i<=5 ; i++) {

if (semop(semID, &acquire, 1) == -1) {


perror(“Consumer waiting");
exit(2);
}

if ((fptr = fopen(PUB7645, "r")) == NULL) {


perror(PUB7645);
exit(3);
}

fscanf(fptr, "%d", &intValue);


fclose(fptr);

11/08/24 Dr. Tang, FDU 18


if (semop(semID, &release, 1) == -1) {
perror(“Release");
exit(4);
}

printf("%d\t", intValue);
}
printf("\nI am process %d. I got five numbers ", getpid());
printf("from a producer as above.\n");
if (semctl(semID, 0, IPC_RMID, 0) == -1) {
perror(“semctl: IPC_RMID”);
exit(5);
}
}

11/08/24 Dr. Tang, FDU 19


Semaphores
• System Call semctl() - signature

Include Files <sys/types.h> <sys/ipc.h> <sys/sem.h>


Summary int semctl(int semid, int semnum,
int cmd, /*union semun arg*/);
Return Success Failure Sets errno
0 or the value -1 Yes
requested by cmd

11/08/24 Dr. Tang, FDU 20


Semaphores
• System Call semctl() - arguments
– The 1st argument is a valid semaphore identifier that
was returned by a previous semget system call.
– The 2nd one is the number of semaphores in the
semaphore set or semaphore index.
– The 3rd one is an integer command value(usually
expressed as one of the symbolic constants found in
the header files <sys/ipc.h> or <sys/sem.h>).
– The 4th one is a union of type semun. Depending on
the action specified by the preceding cmd argument,
the value in arg is either an integer, a reference to a
semid_ds structure or the base address of an array
of short integers.
11/08/24 Dr. Tang, FDU 21
Semaphores
• System Call semctl() – cmd values
– These values cause semctl to act upon the
system semaphore structure (semid_ds).
– IPC_STAT: Return the current values of the
semid_ds for the indicated semaphore
identifier.
– IPC_RMID: Remove the semaphore set
associated with the semaphore identifier.

11/08/24 Dr. Tang, FDU 22


Semaphores
• System Call semctl() – cmd values
– IPC_SET: Modify a restricted number of
members in the semid_ds structure. The
members sem_perm.uid, sem_perm.gid
and sem_perm.mode can be changed if the
effective ID of the accessing process is that of
the superuser, or is the same as the ID value
stored in sem_perm.cuid or
sem_perm.uid.

11/08/24 Dr. Tang, FDU 23


Semaphores
• System Call semctl() – cmd values
– The following cmd values will cause semctl to
act upon the entire set of semaphores:
– GETALL: Return the current values of the
semaphore set. The values are returned via the
array reference passed as the 4th argument to
semctl.
– SETALL: Initialize all semaphores in a set to
the values stored in the array referenced by the
the 4th argument to semctl.

11/08/24 Dr. Tang, FDU 24


Semaphores
• System Call semctl() – cmd values
– Here is the last set of semctl cmd values which acts
upon individual semaphores or upon specific
members in the semid_ds structure. All of these
commands require read permission, except for
SETVAL that requires alter permission.
– GETVAL: Return the current value of the
individual semaphore referenced by the value of the
semnum argument.
– SETVAL: Set the value of the individual semaphore
referenced by the semnum argument to the value
specified by the 4th argument to semctl.

11/08/24 Dr. Tang, FDU 25


Semaphores
• System Call semctl() – cmd values
– GETPID: Return the process ID from the sem
structure within the semid_ds structure.
– GETNCNT: Return the number of processes
waiting for the semaphore referenced by the
semnum argument to increase in value.
– GETZCNT: Return the number of processes
waiting for the semaphore referenced by the
semnum argument to become zero.

11/08/24 Dr. Tang, FDU 26


Semaphores
• System Call semctl() – application
if ((sem_id = semget(ipc_key, NS, IPC_CREAT | 0666)) == -1) {
perror(“semget: IPC_CREAT | 0666”);
exit(1);
}
……
if (semctl(sem_id, 0, IPC_STAT, arg) == -1) { /*show info*/
perror(“semctl: IPC_STAT”);
exit(2);
}
……

11/08/24 Dr. Tang, FDU 27


/*Set arg (the union) to the addr of the initializing vector*/
if (semctl(sem_id, 2, SETALL, arg) == -1) {
perror(“semctl: SETALL”);
exit(3);
}
……
/*Display contents*/
if (semctl(sem_id, i, GETVAL, 0) == -1) {
perror(“semctl: GETVAL”);
exit(4);
}
…… /*Remove semaphore*/
if (semctl(sem_id, 0, IPC_RMID, 0) == -1) {
perror(“semctl: IPC_RMID”);
exit(5);
}
11/08/24 Dr. Tang, FDU 28
Semaphores
• System Call semop() - signature

Include Files <sys/types.h> <sys/ipc.h> <sys/sem.h>


Summary int semop(int semid, struct sembuf *sops,
size_t nsops);
Return Success Failure Sets errno
0 -1 Yes
This call is used to accomplish additional operations on
individual semaphores.

11/08/24 Dr. Tang, FDU 29


Semaphores
• System Call semop() – arguments
– The semop system call requires three arguments
and returns an integer value.
– The 1st argument is the semaphore identifier
returned by a previous successful call to
semget.
– The 2nd argument is a reference to the base
address of an array of semaphore operations
that will be performed on the semaphore set
denoted by the semid value.
– The 3rd is the number of elements in the array of
semaphore operations.

11/08/24 Dr. Tang, FDU 30


Semaphores
• System Call semop() – sembuf structure
– Each element of the semaphore operation array
is a structure of type sembuf which is in the
include file, <sys/sem.h>.
/* User semaphore template for semop system calls*/
struct sembuf {
ushort sem_num; /*semaphore number/index*/
short sem_op; /*semaphore operation*/
short sem_flg; /*operation flags*/
}

11/08/24 Dr. Tang, FDU 31


Semaphores
• System Call semop() – sembuf members
– The 1st member is the semaphore number(i.e., the
index into the array of sem structures referenced by
the sem_base member of the semid_ds
structure).
– The 2nd is the operation to be performed on the
semaphore. A positive integer value means to
increment the semaphore (in general, indicating a
release or return of resource), a negative value for
sem_op means to decrement the semaphore(an
attempt to acquire a resource) and a value of 0
means to test if the semaphore is currently at 0(in
use – all resources allocated).
11/08/24 Dr. Tang, FDU 32
Semaphores
• System Call semop() – sembuf members
– The 3rd is an operation flag which could be one
of IPC_NOWAIT or SEM_UNDO.
– IPC_NOWAIT: If the semaphore operation
cannot be performed (such as when attempting
to decrement a semaphore or test if it is equal to
zero), the call will return immediately.
– SEM_UNDO: If IPC_NOWAIT has not been
indicated, the SEM_UNDO flag allows an
operation to be undone if a blocked
operation(one waiting for a specific condition)
subsequently fails.
11/08/24 Dr. Tang, FDU 33
Semaphores
• System Call semop() – application
– This application is an implementation of producer-
consumer relationship, Program 7.4.
– The producer process generates an integer value that
is stored in a non-shareable resource. It uses two
semaphores to prevent it from overwriting a
previously stored integer value before the consumer
process has retrieved it.
– The consumer process, once a new value has been
generated, retrieves the value from the same file and
displays the value to the screen. It also uses two
semaphores to prevent it from retrieving the same
value multiple times.
11/08/24 Dr. Tang, FDU 34

You might also like