Escolar Documentos
Profissional Documentos
Cultura Documentos
In this section of the tutorial module, we look at two different interprocess communication problems. In each subsection, the problem is presented, followed by explanations of possible solutions using each of the three types of interprocess communication we have discussed. THE AQUA LINE Producer/Consumer Problems Readers/Writers Problems
IPC Home
Subway Page
(1) The producer must first create a new widget. (2) Then, it checks to see if the buffer is full. If it is, the producer will put itself to sleep until the consumer wakes it up. A "wakeup" will come if the consumer finds the buffer empty.(3) Next, the producer puts the new widget in the buffer. If the producer goes to sleep in step (2), it will not wake up until the buffer is empty, so the buffer will never overflow. (4) Then, the producer checks to see if the buffer is empty. If it is, the producer assumes that the consumer is sleeping, an so it will wake the consumer. Keep in mind that between any of these steps, an interrupt might occur, allowing the consumer to run.
(1) The consumer checks to see if the buffer is empty. If so, the consumer will put itself to sleep until the producer wakes it up. A "wakeup" will occur if the producer finds the buffer empty after it puts an item into the buffer. (2) Then, the consumer will remove a widget from the buffer. The consumer will never try to remove a widget from an empty buffer because it will not wake up until the buffer is full.(3) If the buffer was full before it removed the widget, the consumer will wake the producer. (4) Finally, the consumer will consume the widget. As was the case with the producer, an interrupt could occur between any of these steps, allowing the producer to run.
BufferSize = 3; count = 0; Producer() { int widget; WHILE (true) { make_new(widget); IF(count==BufferSize) Sleep(); put_item(widget); count = count + 1; IF (count==1) Wakeup(Consumer); } } Consumer() { int widget; WHILE(true) { IF(count==0) Sleep(); remove_item(widget); count = count + 1; IF(count==N-1) Wakeup(Producer); Consume_item(widget); } } In the next three sections, the Purple Line, we will discuss solutions to this problem using each of the three methods introduced in the Solution Types section:
// loop forever // create a new widget to put in the buffer // if the buffer is full, sleep // put the item in the buffer // increment count of items // if the buffer was previously empty, wake // the consumer
// loop forever // if the buffer is empty, sleep // take an item from the buffer // decrement count of items // if buffer was previously full, wake // the producer // consume the item
Subway Map
Problems
Readers/ Writers
In the following example there are three semaphores. Full, used for counting the number of slots that are full; empty, used for counting the number of slots that are empty; and mutex, used to enforce mutual exclusion. BufferSize = 3; semaphore mutex = 1; semaphore empty = BufferSize; semaphore full = 0; Producer() { // Controls access to critical section // counts number of empty buffer slots // counts number of full buffer slots
int widget; while (TRUE) { make_new(widget); down(&empty); down(&mutex); put_item(widget); up(&mutex); up(&full); } } Consumer() { int widget; while (TRUE) { down(&full); down(&mutex); remove_item(widget); up(&mutex); up(&empty); consume_item(widget); } } // // // // // // // loop forever decrement the full semaphore enter critical section take a widget from the buffer leave critical section increment the empty semaphore consume the item // // // // // // // loop forever create a new widget to put in the buffer decrement the empty semaphore enter critical section put widget in buffer leave critical section increment the full semaphore
// // // //
if buffer is full, block put item in buffer increment count of full slots if buffer was empty, wake consumer
if (count == 0) wait(empty); remove_item(widget); count = count - 1; if (count == N-1) signal(full); } count = 0; end monitor; Producer(); { while (TRUE) { make_item(widget); ProducerConsumer.enter; } } Consumer(); { while (TRUE) { ProducerConsumer.remove; consume_item; } }
// // // //
if buffer is empty, block remove item from buffer decrement count of full slots if buffer was full, wake producer
Subway Map
Problems
Producer/ Consumer
Message Passing
// message buffer
while (TRUE) { make_item(widget); receive(consumer, &m); build_message(&m, widget); send(consumer, &m); } } Consumer() { int widget; message m; for(0 to N) send(producer, &m); while (TRUE) { receive(producer, &m); extract_item(&m, widget); send(producer, &m); consume_item(widget); } }
// // // //
create a new item wait for an empty message to arrive make a message to send to the consumer send widget to consumer
// // // //
get message containing a widget take item out of message reply with an empty message consumer the item
Subway Map
Problems
Producer/ Consumer
Subway Map
Problems
Producer/ Consumer
// Controls access to the reader count // Controls access to the database // The number of reading processes accessing the data
Reader() { while (TRUE) { // loop forever down(&mutex); // gain access to reader_count reader_count = reader_count + 1; // increment the reader_count if (reader_count == 1) down(&db); // if this is the first process to read the database, // a down on db is executed to prevent access
to the up(&mutex); read_db(); down(&mutex); reader_count = reader_count - 1; if (reader_count == 0) up(&db); the // database, allow writing process to access the data up(&mutex); reader_countuse_data(); critical) } Writer() { while (TRUE) { create_data(); critical) down(&db); write_db(); up(&db); } // allow other processes to access // use the data read from the database (non// // // // // database by a writing process allow other processes to access reader_count read the database gain access to reader_count decrement reader_count
// loop forever // create data to enter into database (non// gain access to the database // write information to the database // release exclusive access to the database
IPC Home
Subway
Problems
Readers/
Monitors
Page
Map
Writers
procedure StartWrite() { if ( busy || ReaderCount != 0 ) OKtoWrite.wait(); busy = true; } procedure EndWrite() { busy = false; If (OKtoRead.Queue) OKtoRead.signal(); else OKtoWrite.signal(); } Reader() { while (TRUE) // loop forever { ReadersWriters.StartRead();
readDatabase(); ReadersWriters.EndRead(); } }
Writer() { while (TRUE) // loop forever { make_data(&info); // create data to write ReaderWriters.StartWrite(); writeDatabase(); // call writeDatabase function in monitor ReadersWriters.EndWrite(); } }
Subway Map
Problems
Readers/ Writers
Message Passing
Reader() { while (TRUE) { send (server, ReadRequest); receive (server, value); display (value); } } Writer() {
while (TRUE) { create_data (&value); send (server, WriteRequest, value); receive (server, WriteOk); } }
Subway Map
Problems
Readers/ Writers