1 / 76

Inter Process Synchronization and Communication

Inter Process Synchronization and Communication. CT213 – Computing Systems Organization. Content. Parallel computation Process interaction Processes unaware of each other Processes indirectly aware of each other Processes directly aware of each other Critical sections Mutual exclusion

kuper
Download Presentation

Inter Process Synchronization and Communication

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Inter Process Synchronization and Communication CT213 – Computing Systems Organization

  2. Content • Parallel computation • Process interaction • Processes unaware of each other • Processes indirectly aware of each other • Processes directly aware of each other • Critical sections • Mutual exclusion • Software approaches (Dekker Algorithm, Peterson’s Algorithm) • Hardware approaches (Interrupt disabling, ISA modification) • Semaphores & mutual exclusion with semaphores • Producer Consumer problems • Semaphores implementation • Messages & design issues • Readers/Writers problem

  3. Parallel Computation • Is made up from multiple, independent parts that are able to execute simultaneously using one part per process or thread • In some cases, different parts are defined by one program, but in general they are defined by multiple programs; • Cooperation is achieved through logically shared memory that is used to share information and to synchronize the operation of the constituent processes • The operating system should provide at least a base level mechanism to support sharing and synchronization among a set of processes

  4. Operating System Concerns • Keep track of active processes – done using process control block • Allocate and de-allocate resources for each active process (Processor time, Memory, Files, I/O devices) • Protect data and resources against unwanted interference from other processes • Programming errors done in one process should not affect the stability of other processes in the system • Result of process must be independent of the speed of execution of other concurrent processes • This includes process interaction and synchronization and it is subject of this presentation

  5. Process Interaction • Processes unaware of each other • Independent processes that are not intended to work together; i.e. two independent applications want to access same printer or same file; the operating system must regulate these accesses; these processes exhibit competition • Processes indirectly aware of each other • Processes that are not aware of each other by knowing each other’s process ID, but they are sharing some object (such as an I/O buffer); such processes exhibit cooperation • Process directly aware of each other • These are processes that are able to communicate to each other by means of process IDs; they are usually designed to work jointly on some activity; these processes exhibit cooperation

  6. Competition Among Processes for Resources • Two or more processes need to access a resource • Each process is not aware of the existence of the other • Each process should leave the state of the resource it uses unaffected (I/O devices, memory, processor, etc) • Execution of one process may affect the execution of the others • Two processes wish access to single resource • One process will be allocated the resource, the other one waits (therefore slowdown) • Extreme case: waiting process may never get access to the resource, therefore never terminate successfully • Control problems: • Mutual Exclusion • Critical sections • Only one program at a time is allowed in a critical section • i.e. only one process at a time is allowed to send command to the printer • Deadlock • P1 and P2 with R1 and R2; each process needs to access both resources to perform part of its function; R1 gets allocated to P2 and R2 gets allocated to P1 … both processes will wait indefinitely for the resources … deadlock • Starvation • P1, P2, P3 and resource R … P1 and P3 take successively access to resource R … P2 may never get access to it, even if there is no deadlock situation … starvation

  7. Cooperation Among Processes by Sharing • Processes that interact with other processes without being aware of them • i.e. multiple processes that have access to global variables, shared files or databases • The control mechanism must ensure the integrity of the shared data • Control problems: • Deadlock • Starvation • Mutual exclusion • Data coherence • Data items are accessed in two modes: read and write • Writing must be mutually exclusive to shared resources • Critical sections are used to provide data integrity

  8. Cooperation Among Processes by Communication • When processes cooperate by communication, various processes participate in a common effort that links all of the processes • Communication provides a way to sync or coordinate the various activities • Communication can be characterized by sending/receiving messages of some sort • Mutual exclusion is not a control requirement since nothing is shared between process in the act of passing messages • Control problems: • Possible to have deadlock • Each process waiting for a message from the other process • Possible to have starvation • Two processes sending message to each other while another process waits for a message

  9. Example of Communication by Sharing problems • Process 1 KEYBOARD: • Services the keyboard interrupts • The read characters are placed in a keyboard buffer • Process 2 DISPLAY • Displays the content of buffer on the monitor • Shared resources: • Input buffer • Characters counter of how many chars in buffer and not displayed

  10. KEYBOARD and DISPLAY processes Keyboard Process • ld AC, counter • inc AC • store AC, counter • … • … Display process • ld AC, counter • dec AC • store AC, counter • … • … • If KEYBOARD process is interrupted after instruction “1” (its registers (context) are saved and restored when gains the control of the CPU back) and the control passed to the process DISPLAY, the value of the counter variable will be altered, the two processes will continue to function improperly from this time forward … • Causes for malfunction: • The presence of two copies of same counter variable, one in memory and one in AC with different values • Parallel execution of the two processes • Situations where two or more processes are reading or writing some shared data and the final result depends on who runs precisely when, are called race conditions

  11. Critical Sections • Are parts of the code (belonging to a process) that during execution has exclusive control over a system resource • It has a well defined beginning and end • During the execution of the critical section, the process can’t be interrupted and the control of the processor given to another process that is using same system resource • At a given moment, there is just one active critical section corresponding to a given resource • A critical section is executed in mutual exclusion mode • Critical section examples: • Value update for a global shared variable • Modification of a shared database record • Printing to a shared printer

  12. Mutual Exclusion • If we could arrange matters so no two processes were ever in their critical regions at the same time, we could avoid race conditions • This requirement avoids race conditions, but is not sufficient for having parallel processes cooperate correctly and efficiently using shared data. Four conditions to achieve good results: • No two processes may be simultaneously inside their critical regions (have mutual exclusion) • No assumption may be made about speeds and number of CPUs (independence of speed and number of processors) • No process outside critical section may block other processes (correct functionality is to be guaranteed if one of the processes is abnormally terminated outside of the critical section) • No process would have to wait forever to enter its critical section (the access in the critical section is guaranteed in a finite time)

  13. Mutual Exclusion • While one process is busy updating shared memory (or modifying a shared resource) in its critical region, no other process will enter its critical region and cause trouble • There are a number of different approaches: • Software approaches • Dekker Algorithm • Peterson’s Algorithm • Hardware approaches • Interrupt disabling • ISA modification

  14. Dekker’s Algorithm – First Attempt void proc2(){ while (TRUE){ while (turn ==PROC1){;} /*critical section code */ turn = PROC1; something_else(); } } void proc1(){ while (TRUE){ while (turn ==PROC2){;} /*critical section code */ turn = PROC2; something_else(); } } int turn; /*global variable*/ main(){ turn = PROC1; init_proc(&proc1(), …); init_proc(&proc2(), …); } • turn – global memory location that both processes could access; each process examines the value of turn, if it is equal to the number of process, then the process could proceed to the critical section • This procedure is known as busy waiting, since the processes are waiting (doing nothing productive but taking processor) to get the access to critical section • Mutual exclusion conditions: • Satisfied • Unsatisfied – processes can be executed alternatively only, thus, the rhythm of execution is given by the slower process • Unsatisfied – abnormal termination of one process determines blocking of the other • Satisfied

  15. Dekker’s Algorithm – Second Attempt void proc1(){ while (TRUE){ while (p2use ==TRUE){;} p1use = TRUE; /*critical section code */ p1use = FALSE; something_else(); } } void proc2(){ while (TRUE){ while (p1use ==TRUE){;} p2use = TRUE; /*critical section code */ p2use = FALSE; something_else(); } } /*global variables*/ int p1use, p2use; main(){ p1use = FALSE; p2use = FALSE; init_proc(&proc1(), …); init_proc(&proc2(), …); } • The problem with first attempt is that it stores the name of the process that may enter its critical section, when in fact we need state information about both processes • Each process has to have its key to the critical section, so if one process fails, the other could still have access to the critical section • Mutual exclusion conditions: • Unsatisfied – if process proc1 is getting interrupted right before have set p1use = TRUE, and the second process takes over the processor, then at one stage both processes will have access to the critical section • Satisfied • Satisfied if the processes are not failing in the critical section or during setting the flags • Satisfied

  16. Dekker’s Algorithm – Third Attempt void proc1(){ while (TRUE){ p1use = TRUE; while (p2use ==TRUE){;} /*critical section code */ p1use = FALSE; something_else(); } } void proc2(){ while (TRUE){ p2use = TRUE; while (p1use ==TRUE){;} /*critical section code */ p2use = FALSE; something_else(); } } int p1use, p2use; /*global variables*/ main(){ p1use = FALSE; p2use = FALSE; init_proc(&proc1(), …); init_proc(&proc2(), …); } • Because one process could change its state after the other checked it, both processes could go in the critical section, so the second attempt failed • Perhaps we could change this with just changing the position of two statements … • Mutual exclusion conditions: • Satisfied • Satisfied • Satisfied if the processes are not failing in the critical section or during setting the flags; Unsatisfied otherwise (the other process is blocking) • Unsatisfied – if both processes set their flags to true before either of them has executed the while statement, then each will think that the other has entered its critical section, causing deadlock

  17. Dekker’s Algorithm – Forth Attempt void proc1(){ while (TRUE){ p1use = TRUE; while (p2use ==TRUE){ p1use = FALSE; delay(…); p1use = TRUE; } /*critical section code */ p1use = FALSE; something_else(); } } void proc2(){ while (TRUE){ p2use = TRUE; while (p1use ==TRUE){ p2use = FALSE; delay(…); p2use = TRUE; } /*critical section code */ p2use = FALSE; something_else(); } } int p1use, p2use; /*global variables*/ main(){ p1use = FALSE; p2use = FALSE; init_proc(&proc1(), …); init_proc(&proc2(), …); } • Third algorithm failed because deadlock occurred as result of irreversibly change of each process’s state to TRUE before actually having the test done. No way back off from this position • Try to fix this by having each process to indicate its desire to enter the critical section, but it is prepared to defer to the other process • Mutual exclusion conditions: • Satisfied • Unsatisfied – if the processes are executing with exact speed, then neither of the processes will enter the critical section • Satisfied if the processes are not failing in the critical section or during setting the flags; Unsatisfied otherwise (the other process is blocking) • Satisfied

  18. Dekker’s Algorithm – Correct Version void proc1(){ while (TRUE){ p1use = TRUE; while (p2use ==TRUE){ if (turn == PROC2){ p1use = FALSE; while (turn ==PROC2){;} p1use = TRUE; } } /*critical section*/ turn = PROC2; p1use = FALSE; something_else(); } } void proc2(){ while (TRUE){ p2use = TRUE; while (p1use ==TRUE){ if (turn == PROC1){ p2use = FALSE; while (turn ==PROC1){;} p2use = TRUE; } } /*critical section code */ turn = PROC1 p2use = FALSE; something_else(); } } int p1use, p2use, turn; /*global variables*/ main(){ p1use = FALSE; p2use = FALSE; turn = PROC1; init_proc(&proc1(), …); init_proc(&proc2(), …); } • It is an algorithm that respects the 4 conditions of mutual exclusion, but only for two concurrent processes. • Mutual exclusion conditions: • Satisfied • Satisfied • Satisfied • Satisfied

  19. Peterson’s Algorithm void proc2(){ while (TRUE){ p2use = TRUE; turn = PROC1; while (p1use ==TRUE && turn==PROC1){;} /*critical section*/ p1use = FALSE; something_else(); } } void proc1(){ while (TRUE){ p1use = TRUE; turn = PROC2; while (p2use ==TRUE && turn==PROC2){;} /*critical section*/ p1use = FALSE; something_else(); } } • If proc2 is in its critical section, then p2use = TRUE and proc1 is blocked from entering its critical section. • Peterson’s Algorithm can be easily generalized for n threads • Mutual exclusion conditions: • Satisfied • Satisfied • Satisfied • Satisfied int p1use, p2use; int turn; main(){ p1use = FALSE; p2use = FALSE; init_proc(&proc1(), …); init_proc(&proc2(), …); }

  20. Hardware Solutions - Disabling Interrupts • Simplest solution is to have the process disable interrupts right after entering the critical region and enable them just before leaving it • With interrupts disabled, no interrupts will occur; • The processor is switched from process to process only as result of interrupt occurrence, so the processor will not be switched to other process • It is unwise to give a user process the power to turn off interrupts • Suppose it did it and never turn them on again … • Suppose it is a multi-processor system …disabling interrupts on one of them, will not help too much • It is a useful technique within the operating system itself, but it is not appropriate as general mutual exclusion mechanism for user processes while (TRUE){ /*disable interrupts*/ /*critical section*/ /*enable interrupts*/ something_else(); }

  21. Special Machine Instructions • In a multiprocessor configuration, several processors share access to a common main memory; the processors behave independently • There is no interrupt mechanism between processors on which mutual exclusion can be based • At a hardware level, access to a memory location excludes any other access to same memory location; based on this, several machine level instructions to help mutual exclusion have been added. Most common ones: • Test & Set Instruction • Exchange Instruction • Because those operations are performed in a single machine cycle, they are not subject to interference from other instructions

  22. Test & Set Instruction /*test & set instruction */ boolean testset (int i) { if (i==0){ i=1; return TRUE; } else{ return FALSE; } } void proc(int i){ while (TRUE){ while (!testset(bolt)){;} /*critical section*/ bolt = 0; something_else(); } } /*number of processes*/ const int n = 2; int bolt; main(){ int i; i=n; bolt = 0; while (i >0){ init_proc(&proc1(i), …); i--; } } • The shared variable bolt is initialized to 0; • The only process that may enter its critical section is the one that finds the bolt variable equal to 0 • All processes that attempt to enter the critical section go into a busy waiting mode • When a process leaves the critical section, it resets bolt to 0; at this point only one from the waiting processes is granted access to the critical section

  23. Exchange Instruction /*exchange instruction */ void exchange (int register, int memory) { int temp; temp = memory; memory = register; register = temp; } void proc(int i){ int keyi; while (TRUE){ keyi=1; while (keyi != 0){ exchange(keyi, bolt); } /*critical section*/ exchange (keyi, bolt); something_else(); } } /*number of processes*/ const int n = 2; int bolt; main(){ int i; i=n; bolt = 0; while (i >0){ init_proc(&proc1(i), …); i--; } } • The instruction exchanges the contents of a register with that of a memory location; during the execution of the instruction, access to that memory location is blocked for any other instruction • The shared variable bolt is initialized to 0; each process holds a local variable key that is initialized to 1 • The only process that enters the critical section is the one that finds the variable bolt equal to 0;

  24. Properties of Hardware Approach • Advantages: • Simple and easy to verify • It is applicable to any number of processes on either a single processor or multiple processors sharing main memory • It can be used to support multiple critical sections, each critical section defined by its own global variable • Problems: • Busy waiting is employed • Starvation is possible – selection of a waiting process is arbitrary, thus some process could indefinitely be denied access • Deadlock is possible – consider following scenario: • P1 executes special instruction (test&exchange) and enters its critical section • P1 is interrupted to give the processor to P2 (which has higher priority) • P2 wants to use same resource as P1 so wants to enter critical section so, it will test the critical section variable and wait • P1 will never be dispatched again because it is of lower priority than another ready process, P2

  25. Semaphores • Because of the drawback of both the software and hardware solutions, we need to look into other solutions • Dijkstra defined semaphores • Two or more processes can cooperate by means of simple signals, such that a process can be forced to stop at a specific place until it has received a specific signal • For signaling, special variables, called semaphores are used

  26. Semaphores • Special variable called a semaphore is used for signaling • to transmit a signal, execute signal(s) • Dijkstra used V for signal (increment - verhogen in Dutch) • to receive a signal, execute wait(s) • Dijkstra used P for wait (test - proberen in Dutch) • If a process is waiting for a signal, it is suspended until that signal is sent • Wait and Signal operations cannot be interrupted • A queue is used to hold processes waiting on the semaphore

  27. Semaphores – Simplified view • We can view the semaphore as a variable that has an integer value; three operations are defined upon this value: • A semaphore may be initialized to a non-negative value • The wait operation decrements the semaphore value. If the value becomes negative, then the process executing wait is blocked • The signal operation increments the semaphore value. If the value is not positive, then a process blocked by a wait operation is unblocked

  28. Semaphores – Formal view struct semaphore { int count; queueType queue; } void wait(semaphore s) { s.count--; if (s.count < 0) { place this process in s.queue; block this process } } void signal(semaphore s) { s.count++; if (s.count <= 0) { remove a process P from s.queue; place process P on ready list; } } • A queue is used to hold processes waiting on a semaphore • What order should the processes be removed • Fairest policy is FIFO, a semaphore that implements this is called strong semaphore • A semaphore that doesn’t specify the order in which processes are removed from the queue is known as week semaphore

  29. Binary Semaphores struct binary_semaphore { enum (zero, one) value; queueType queue; }; void waitB(binary_semaphore s){ if (s.value == 1) s.value = 0; else{ place this process in s.queue; block this process; } } void signalB(semaphore s){ if (s.queue.is_empty()) s.value = 1; else{ remove a process P from s.queue; place process P on ready list; } } • A more restrictive version of semaphores • A binary semaphore may take on the values 0 or 1. • In principle it should be easier to implement binary semaphores and they have expressive power as the general semaphore • Both semaphores and binary semaphores do have a queue to hold the waiting processes

  30. Example of Semaphore Mechanism • Processes A, B and C depend on the results from process D • Initially, process D has produced an item of its resources and it is available (the value of the semaphore is s=1)

  31. (1) A is running, B, D and C are ready; When A issues a wait(s) it will immediately pass the semaphore and will be able to continue its execution, so it rejoins the ready queue • (2) B runs and will execute a wait(s) primitive and it is suspended (allowing D to run) • (3) D completes a new result and issues a signal(s)

  32. (4) signal(s) from (3) allows B to move in ready queue; D rejoins the ready queue and C is allowed to run • (5) C is suspended when it issues a wait(s), similarly A and B are suspended on the semaphore • (6) D takes processor again and produces one reslut again, calling signal(s); • (7) C is removed from the semaphore queue and placed in ready list • Latter cycles of D will release A and B from suspension

  33. Mutual Exclusion with Semaphores /* program mutual exclusion */ const int n = 3; /* number of processes */; semaphore lock = 1; void P(int i){ while (true){ waitB(lock); /* critical section */; signalB(lock); /* other processing*/; } } void main(){ int i; i=n; while (i>0){ init_proc(&proc(i), …); i--; } }

  34. Producer/Consumer Problem • Problem formulation: • One or more producers generating some type of data (i.e. records, characters, etc…) and placing these in a buffer • Consumer that are taking items out of the buffer, one at a time; only one agent (either producer or consumer can access the buffer at a time) • The system is to be constrained to prevent the overlap of buffer operations • Examine a number of solutions to this problem

  35. Infinite linear array buffer producer: while (true) { /* produce item v */ Buff[in] = v; in++; } consumer: while (true) { while (in <= out) {;}/*do nothing */; w = Buff[out]; out++; /* consume item w */ } • Consumer has to make sure that will not read data from an empty buffer (makes sure in >out) • Try to implement this using binary semaphores Note: shaded area indicates occupied locations

  36. One producer, One consumer, Infinite buffer • product is a semaphore that counts the number of objects placed in the buffer and not consumed yet • Product is (in – out) (see the previous buffer) • This solution works only if there is just one consumer, one producer and the intermediary buffer is infinite. If multiple producers/consumers than the append() and take() need to be serialized (as they increment/decrement buffer pointers) void producer(){ while (TRUE){ produce_object(); append(); signal(product); something_else(); } } void consumer{ while (TRUE){ wait(product); take(); consume_object(); something else(); } } main(){ create_semaphore(product); init_proc(&producer(), …); init_proc(&consumer(), …); }

  37. Multiple producers, Multiple consumers and infinite buffer • buff_access_prod is a semaphore that synchronizes the access of producers to the buffer • buff_access_cons is a sempahore that synchronizes the access of the consummers to the buffer • product is a semaphore that counts the produced objects yet unconsumed main(){ create_semaphore(product); create_semaphore(buff_access_prod); create_semaphore(buff_access_cons); init_proc(&producer1(), …); init_proc(&producer2(), …); /*…*/ init_proc(&producerN(), …); init_proc(&consumer1(), …); init_proc(&consumer2(), …); /*…*/ init_proc(&consumerM(), …); } void producerX(){ while (TRUE){ produce_object(); wait(buff_access_prod); append(); signal(buff_access_prod); signal(product); something_else(); } } void consumerY{ while (TRUE){ wait(product); wait(buff_access_cons); take(); signal(buff_access_cons); consume_object(); something else(); } }

  38. Finite (circular) buffer producer: while (true) { /* produce item v */ /* do nothing while buffer full */; while ((in + 1)%n==out){;} Buff[in] = v; in = (in + 1) % n } consumer: while (true) { /* do nothing while no data */; while (in == out){;} w = Buff[out]; out = (out + 1) % n; /* consume item w */ } • Block: (i) Producer – insert in full buffer (ii) Consumer – remove from empty buffer • Unblock: (i) Consumer – remove item (ii) Producer – insert item Note: shaded area indicates occupied locations

  39. Multiple producers, Multiple consumers, Finite buffer • buff_space – semaphore that counts the free space from the buffer • product – semaphore that counts the produced items and not consumed yet • buff_access_prod is a semaphore that synchronizes the access of producers to the buffer • buff_access_cons is a semaphore that synchronizes the access of the consumers to the buffer main(){ create_semaphore(product); create_semaphore(buff_access_prod); create_semaphore(buff_access_cons); create_semaphore(buff_space); /*initialize the buff_space semaphor to the size of the buffer*/ init_proc(&producer1(), …); init_proc(&producer2(), …); /*…*/ init_proc(&producerN(), …); init_proc(&consumer1(), …); init_proc(&consumer2(), …); /*…*/ init_proc(&consumerM(), …); } void producerX(){ while (TRUE){ produce_object(); wait (buff_space); wait(buff_access_prod); append(); signal(buff_access_prod); signal(product); something_else(); } } void consumerY{ while (TRUE){ wait(product); wait(buff_access_cons); take(); signal(buff_access_cons); signal(buff_space); consume_object(); something else(); } }

  40. Semaphores implementation • As mentioned earlier, it is imperative that the wait and signal operations to be atomic primitives • The essence of the problem is mutual exclusion • Only one process at a time may manipulate a semaphore with either a wait or signal operation • Any of the software schemas would do (Peterson’s and Dekker’s algorithms) • Large amount of processing overhead • The alternative is to use hardware supported schemas for mutual exclusion • Semaphores implemented with test&set instruction • Semaphores implemented with disable/enable interrupts

  41. Semaphores implementation with test&set • The semaphore s is a structure, as explained earlier, but now includes a new integer component, s.flag • This involves a form of busy waiting, but the primitives wait and signal are short, so the amount of waiting time involved should be minor wait(s){ while (!testset(s.flag))/* do nothing */; s.count--; if (s.count < 0){ /*place this process in s.queue; block this process*/ } s.flag = 0; } signal(s){ while (!testset(s.flag)){;} /*do nothing*/ s.count++; if (s.count <= 0){ /*remove a process P from s.queue; place process P on ready list*/ } s.flag = 0; }

  42. Semaphores implemented using interrupts • For single processor system it is possible to inhibit the interrupts for the duration of a wait or signal operation • The relative short duration of these operations means that this approach is reasonable wait(s){ disable_interrupts(); s.count--; if (s.count < 0){ /*place this process in s.queue; block this process } enable_interrupts(); } signal(s){ disable_interrupts(); s.count++; if (s.count <= 0){ /*remove a process P from s.queue; place process P on ready list*/ } enable_interrupts(); }

  43. Inter Process Communication • Inter process data exchange, execution state report, results collection is part of inter process communication; it can be done using some shared memory zones, therefore synchronization is required • Semaphores are primitive (yet powerful) tools to enforce mutual exclusion and for process coordination; still, it may be difficult to produce a correct program using semaphores • The difficulty is caused by the fact that wait and signal operations may be scattered throughout a program and is not easy to see an overall effect

  44. Messages • When a process interacts with another, two main fundamental requirements must be satisfied: communication and synchronization • Message passing provides both of those functions • Message-passing systems come in many forms; this section will provide a general view of typical features found in such systems • The message-passing function is normally provided in the form of primitives: • Send (destination, message) • Receive (source, message)

  45. Messages design issues • Synchronization • Blocking vs. Non-blocking • Addressing • Direct • Indirect • Message transmission • Through value • Through reference • Format • Content • Length • Fixed • Variable • Queuing discipline • FIFO • Priority

  46. Synchronization • Send gets executed in a process • Sending process is blocked until the receiver gets the message • Sending process continues its execution in a non blocking fashion • Receive gets executed in a process • If a message has been previously sent, the message is received and execution continues • If there is no waiting message then • Process can be blocked until a message arrives • The process continues to execute, abandoning the attempt to receive • So both the sender and receiver can be blocking or not

  47. Synchronization … • There are three typical combinations of systems • Blocking send, blocking receive • Both the receiver and sender are blocked until the message is delivered (provides tight sync between processes) • Non-blocking send, blocking receive • The sender can continue the execution after sending a message, the receiver is blocked until message arrives (it is probably the most useful combination) • Non-blocking send, non-blocking receive • Neither party waits • Typically only one or two combinations are implemented

  48. Addressing • Direct addressing • Send primitive include the identifier of the receiving process • Receive can be handled in two ways • Receiving process explicitly designates the sending process (effective for cooperating processes) • Receiving process is not specifying the sending process (known as implicit addressing); in this case, the source parameter of receive primitive has a value returned when the receive operation has been completed • Indirect addressing • The messages are not sent directly from sender to receiver, but rather they are sent to a shared data structure consisting of queues that temporarily can hold messages; those are referred to as mailboxes. • Two communicating process: • One process sends a message to a mail box • Receiving process picks the message from the mailbox

  49. Indirect process communication • Indirect addressing decuples the sender form the receiver allowing for greater flexibility. • Relationship between sender and receiver: • One to one • Private communications link to be set up between two processes • Many to one • Useful for client server interaction; one process provides services to other processes; in this case, the mailbox is known as port • One to many • Message or information is broadcasted across a number of processes • Many to many

  50. Message transmission • Through value • Require temp buffers in the operating system that would store the sent messages until the receiver would receive them • Overloading of the OS • Through reference • Doesn’t require temporary buffers • Faster than the value passing method • Requires protection of the shared memory • It is difficult to implement when the sender and receiver are located on different machines • Mixed passing • The sending is done through reference • If it is the case (the receiver tries to modify the received message), the message gets transmitted again, this time through value

More Related