Upload
gita
View
57
Download
6
Tags:
Embed Size (px)
DESCRIPTION
Semaphores and typical applications. What are semaphores and messages How to control a critical section with semaphores Typical process coordination problems. Semaphore code from Stevens (QEPD). #include // The header file info #include #include - PowerPoint PPT Presentation
Citation preview
Semaphores and typical applications
What are semaphores and messagesHow to control a critical section with
semaphoresTypical process coordination problems
Semaphore code from Stevens (QEPD)
#include <sys/types.h> // The header file info#include <sys/ipc.h> #include <sys/sem.h> #define KEY ((key_t) 54321) // an unlikely key #define COUNT 20000 struct sembuf op_up[1] = { 0, 1, 0 }; // A useful trick for semopsstruct sembuf op_down[1] = { 0, -1, 0 }; // use -1 for down – use this in wrappersmain() {
register int i, semid; // Always protect system codeif ( (semid = semget(KEY, 1, 0666 | IPC_CREAT)) < 0) err_sys("semget error"); for (i = 0; i < COUNT; i++) {
if (semop(semid, &op_up[0], 1) < 0) err_sys("semop up error"); if (semop(semid, &op_down[0], 1) < 0) err_sys("semop down error");
}if (semctl(semid, 0, IPC_RMID, (struct semid_ds *) 0) < 0) err_sys("IPC_RMID error"); exit(0);
}
The header
Concurrency - From last time
The theoretical core of OSAn OS creates a set of processes that run concurrentlyA process is like a person - it has
a stream of consciousnesspossessions - memory, files, datais created, reproduces, diesinteracts with other processesIn actuality, it is a program in execution
Concurrent process misbehaviorsRace conditions - unpredictable results because processes
simultaneously modify data or devicesDeadlocks - Each has what the other wantsStarvation - some processes go hungry - others eat well
Some operating system ideas - also review
Everything is a file - even devices This allows a program to work with human input, or a device, or
a temporary or permanent file
Interrupt-driven behaviorExample - windows - process is simultaneously sensitive to
events from mouse, keyboard, process subsystem, and window manager
Caching - Foreground and background copiesUsed in
Cache memorySwappingThe disk block cache - recent transactions are in
memoryNetworking utilities
Processes and their states
The process state includes the followingRunning/ready/blocked (waiting on an event/events)PriorityKernel/User modeIn-memory/swappedProcess IDPriority
The process ownsU-area (but user can’t examine/modify it)Entries in the system open-file tableIts own file control blocks (linked to the system table)Its own memory space
The system process table
Used for scheduling and control of processesScheduler acts on timer interrupt or a process state change
It schedules the highest-priority process that is ready
It causes a context switch (gives the process control)
This mechanismGives system and I/O processes high priority
Keeps the CPU puercos from monopolizing
Interrupts are outside process countryThis avoids make a context switch for each interrupt
It means the interrupt service routines use only the kernels memory
Mutual Exclusion - software solutions
Unsuccessful solutions (on separate slides)Strict alternation
Algorithms where mutual exclusion fails
Peterson’s algorithm
Description of Bakery AlgorithmJust like Baskin-Robbins - incoming process takes a
number
Since two users can grab same number, lowest-number process gets priority
Avoiding busy waiting - Semaphores and messages
Classical semaphoresThe semaphore is an ADT with a counter, a process queue,
and two operationsThe down operation sleeps enqueued if the counter is zero,
and then decrements the counterThe up operation increments the counter and awakens a
sleeper if the counter was 0.The down operation enters a critical section, the up leaves it.
MessagesReliable messages to an administrator work like a down or up
Messages and semaphores are equivalentThat’s why
Semaphores and messages - continued
Mistakes are easyDeadlock
Gateway-controlling and resource-controlling semaphores invoked in wrong order - deadlocks and slow performance
Example of a deadlock creator
//process 0Wait(a)Wait(b)//critical sectionSignal(a)Signal(b)
//process 1Wait(b)Wait(a)//critical sectionSignal(b)Signal(a) b
a
Process 0 Process 1
If process 1 is like process 0 (semaphores a and b requestedIn same order, this deadlock can’t occur
Producer-consumer problem again
DefinitionProducers
They produce items and place in a buffer as long as one is available.
They wait (and stop producing) when no buffer is available
ConsumersThey wait until a buffer contains an item and then take it
They then consume the item
What needs protectionThe buffer place and take operations, not the producing or
consuming
Possible deadlockProducer is waiting for a consumer to take, but consumer can’t
take because producer has buffering operation locked
This problem can’t be solved with only one semaphore
Producer-consumer with general semaphores
Global variablesItem buffers[Nbuffers];
Int last_filled=N_buffers, oldest_item=0, number_filled=0;
// underrated programming technique, give descriptive and nonambiguous names, not i, j, in, out
SemaphoresBuffer_available=n,items_available=0;pool_available=1;
Technique Circular buffering step operation
Next = (next+1)%N_buffers // steps pointer from end to start
The code itself
Producer() {While(1) {
New_item=produce();Wait (buffer_available);Wait (pool_available);Buffers[next_available]=new_item;Count++;step(last_filled)Signal(items_available);Signal(pool_available);
}}
consumer() {While(1) {
Wait (items_available);Wait (pool_available);Old_item=Buffers[oldest_item];Count--;step(oldest_item)Signal(buffer_available);Signal(pool_available); New_item=produce();
}}
Language Mechanisms - Monitors
Monitor is a class with mutual exclusion: it hasMember functions
Data members
Condition variables (user processes wait on these)
Two ways to enterNormal
Returning from wait on a condition variable
Two ways to leaveNormal (return from a member function)
Waiting on a condition variable
Monitors can be implemented by:Preprocessor that generates semaphore code
Compiler modification
Classical IPC problems
Producer-consumerScenario
Producer produces informationConsumer consumes itBoth must wait on buffer availabilityProblem resembler disk I/O and print servers
Code is in book - both C and monitorReaders-Writers
ScenarioReaders can write whenever no writer is activeWriters must have solitudeProblem resembles database
Code in book - both C and monitorDining Philosophers
ScenarioN philosophers think, wait for chopsticks, and eatProblem is useless but illustrative
Code - both C and monitor
System V IPC
Resource type
Get call Op call Control call
Semaphore set
semget semop semctl
Message queue
msgget msgsndmsgrcv
msgctl
Shared memory region
shmget shmatshmdt
shmctlxxxget call
int xxxget(key, type-dependent, flags)
returnsPositive number, which is the instance ID-For error
-xxxop call-The basic operation-Works on regions, groups of semops, or message queues
xxxctl callDoes specialized operations – removes instance, sets values and permissions
Stevens – semaphore get#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>
#define KEY ((key_t) 98765L)
#define PERMS 0666
main(){
int i, semid;
for (i = 0 ; i < 1000; i++) {if ( (semid = semget(KEY, 1, PERMS | IPC_CREAT)) < 0)
err_sys("can't create semaphore");
printf("semid = %d\n", semid);
if (semctl(semid, 0, IPC_RMID, (struct semid_ds *) 0) < 0)err_sys("can't remove semaphore");
}}
#include "msgq.h"
main(){
int readid, writeid;
/* * Open the message queues. The server must have * already created them. */
if ( (writeid = msgget(MKEY1, 0)) < 0)err_sys("client: can't msgget message queue 1");
if ( (readid = msgget(MKEY2, 0)) < 0)err_sys("client: can't msgget message queue 2");
client(readid, writeid);
/* * Now we can delete the message queues. */
if (msgctl(readid, IPC_RMID, (struct msqid_ds *) 0) < 0)err_sys("client: can't RMID message queue 1");
if (msgctl(writeid, IPC_RMID, (struct msqid_ds *) 0) < 0)err_sys("client: can't RMID message queue 2");
exit(0);}
Wrapper function for msgsnd
mesg_send(id, mesgptr)int id; /* really an msqid from msgget() */Mesg *mesgptr;{
/* * Send the message - the type followed by the optional data. */
if (msgsnd(id, (char *) &(mesgptr->mesg_type),mesgptr->mesg_len, 0) != 0)
err_sys("msgsnd error");}
/* * Receive a message from a System V message queue. * The caller must fill in the mesg_type field with the desired type. * Return the number of bytes in the data portion of the message. * A 0-length data message implies end-of-file. */
Wrapper for msgrcv
intmesg_recv(id, mesgptr)int id; /* really an msqid from msgget() */Mesg *mesgptr;{
int n;
/* * Read the first message on the queue of the specified type. */
n = msgrcv(id, (char *) &(mesgptr->mesg_type), MAXMESGDATA,mesgptr->mesg_type, 0);
if ( (mesgptr->mesg_len = n) < 0)err_dump("msgrcv error");
return(n); /* n will be 0 at end of file */}
Header for both wrapper functions
/* * Definition of "our" message. * * You may have to change the 4096 to a smaller value, if message queues * on your system were configured with "msgmax" less than 4096. */
#define MAXMESGDATA (4096-16)/* we don't want sizeof(Mesg) > 4096 */
#define MESGHDRSIZE (sizeof(Mesg) - MAXMESGDATA)/* length of mesg_len and mesg_type */
typedef struct { int mesg_len; /* #bytes in mesg_data, can be 0 or > 0 */ long mesg_type; /* message type, must be > 0 */ char mesg_data[MAXMESGDATA];} Mesg;
General pattern for an IPC example
Main programCreate the IPC (xxxget)
Initialize the IPC (xxxctl)
Set up the cleanup() function
Create children to be the actors using a loop containing fork()
Does monitoring function or creates a monitor
note: Global variables are usually needed
Child actorsCan be persistent (barbers, philosophers)
Can be temporary (readers, customers, Loreina says writers are immortal)
Either live forever (with while loop) if immortal
Or exit(0) if mortal
Some specifics
DefinitionDecide what IPC is needed and give valid namesDecide what other global variables are needed and what protection is
neededWrite pseudocode, then fill in to readable code
Program operationExamples can be done as real-time (uses sleep()) or discrete-time
simulationDTS is faster, gives better statistics, but takes some thoughtTerminal output can be a problem – output from child needs a flush,
especially if control characters are involvedThink about the statistics, there is usually a dimensionless utilization
parameter or ratioExample of this is ratio of haircutting capacity to offered business in
the barbershop
Example of a cleanup() function
Comments:Cleanup must be declared extern or the signal mechanism won’t find itThis won’t work for all signals, notably 9Response to 9 (SIGKILL) isn’t alterable because it is important to be
able to really control the system
void cleanup() {if (0>(msgctl(semid, IPC_RMID, (struct msqid_ds *) 0) ) error_exit(“couldn’t remove
Message queue”);exit(0);
}
/* code segment to set up signals for cleanupextern void cleanup;…………for (int signal=0;signal<32;signal++) signal(signal,cleanup);
Methodology for the sleepy barber
SemaphoresawaitingBarber –
awaitingCustomer –
mutex – controls waiting-room variables, used whenever a customer arrives or a haircut starts
Global variablesemptyChairs -