1 / 25

Outline

Outline. Processes Threads Inter-process communication (IPC) Classical IPC problems Scheduling. Issues about IPC. Communication between processes is indispensable. Interrupt is not preferred. Why? How about pipe ? Basic issues How to pass information

yuki
Télécharger la présentation

Outline

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. Outline • Processes • Threads • Inter-process communication (IPC) • Classical IPC problems • Scheduling

  2. Issues about IPC • Communication between processes is indispensable. • Interrupt is not preferred. Why? • How about pipe? • Basic issues • How to pass information • How to solve the competition for resources (mutual exclusion) • How to guarantee the dependency (synchronization)

  3. Sharing Resources The next file to print Process A out = 4 in = 7 Process B The next free slot A’s file overwrites B’s!!!

  4. Race Conditions • Two or more processes are reading or writing some shared data, the final result depends on who/when runs precisely • Must be avoided • Solution: mutual exclusion • Critical region/section: the part of program where the shared resource is accessed • No two processes in their critical regions at the same time

  5. Conditions for Sharing Resource • No two processes simultaneously inside their critical regions (mutual exclusion) • No assumption about speeds or number of CPUs • No process running outside its critical region may block other processes • No process waits forever to enter its critical region (no deadlock)

  6. Mutual Exclusion Using Critical Regions A enters critical region A leaves critical region Process A Process B T3 T4 T2 T1 Time

  7. Achieve Mutual Exclusion • Busy waiting • Sleep and wakeup • Semaphores • Mutexes • Monitors • Message passing • Barriers

  8. Busy Waiting – Disabling Interrupts • Enter critical region  disable interrupts  …  enable interrupts  leave critical region • Simplest, intuitive • Why disable interrupt? No process switching in critical region • Problem: lose control of user processes • Not work in the case of multiple CPUs • Good for kernel.

  9. Busy Waiting – Lock Variables • Disable interrupt is not good. • Any software solution? • Lock variable: single, shared variable • Before entering critical region, test and set • Race condition on the lock variable • After one process reads the lock but before it sets to 1, switching happens. • Problem: test and set lock variable must be inseparable, i.e., atomic • Ask for help from hardware

  10. TSL: Help from Hardware • Problem of lock variables • Test, if 0, enter, else wait • What if both process test 0 and enter? • TSL instruction: TSL RX, LOCK • Read, update and write-back • All three operations are indivisible Leave_region: MOV LOCK, #0 RET Enter_region: TSL REG, LOCK CMP REG, #0 JNE Enter_region RET

  11. Busy Waiting: Strict Alternation // Initially turn=0 While (TRUE){ while (turn!=1); /*loop*/ critical_region(); turn=0; non_critical_region(); } While (TRUE){ while (turn!=0); /*loop*/ critical_region(); turn=1; non_critical_region(); } Process 1 Process 0 A process may be blocked by another one not in its critical region! It requires strictly alternate in using critical regions. Process 0 and 1 use critical region alternatively in a strict order!

  12. Get Rid of Strict Alternation • Peterson’s solution: combine taking turns with the idea of lock variables • Two procedures • enter_region and leave_region • For each process • Call enter_region before entering its critical region • Call leave_region after leaving its critical region Process 1:……Enter_region(1);critical_part;Leave_region(1);….. Process 0:……Enter_region(0);critical_part;Leave_region(0);…..

  13. C Code of Peterson’s Solution int turn;// shared variable. whose turn is it? int interested[2];//shared variable. all values initially FALSE Void enter_region(int process) //parameter: 0 or 1 { int other; //local variable. number of the other process other=1-process; //the opposite of process interested[process]=TRUE; //show that you are interested turn=process; //set flag while (turn==process && interested[other]==TRUE); } 1 2 3 Void leave_region(int process) //process: who is leaving? { interested[process]=FALSE //departure from critical region }

  14. void enter_region(int 1) //process=1 { int other; //local variable other=1-process=0; interested[1]=TRUE; turn=1; while (turn==1 && interested[0]==TRUE); } void enter_region(int 0) //process=0 { int other; //local variable other=1-process=1; interested[0]=TRUE; turn=0; while (turn==0 && interested[1]==TRUE); } 1 1 2 2 3 3

  15. Problems of Busy Waiting • Waste CPU time • Some processes may never get chance to run • Priority inversion problem • E.g., L in critical region, while H is busy waiting • Solution: block instead of waiting • sleep and wakeup operations • sleep(): cause the caller to block, until another process wakes it up • wakeup(pid): wake up the process specified by pid

  16. Producer-Consumer Problem • Elements: producer, consumer, buffer • Producer: put items into buffer • Consumer: take items out of buffer • Buffer: fixed size holder of items producer items buffer items consumer

  17. #define N 100 // number of slots in the buffer int count = 0; // number of items in the buffer void producer(void){ int item; while (TRUE){ // repeat forever item = produce_item(); // generate next item if (count == N) sleep();// if buffer is full, go to sleep insert_item(item); // put item into buffer count = count+1; // increment count of items in buffer if (count == 1) wakeup(consumer);// was buffer empty? } } void consumer(void){ int item; while (TRUE){ // repeat forever if (count == 0) sleep();// if buffer is empty, go to sleep item = remove_item(); // take item out of buffer count = count-1; // decrement count of items in buffer if (count == N – 1) wakeup(producer);// was buffer full? consume_item(item); // print item } } Switch to producer. Lost-wakeup call!

  18. Problem: Lost-Wakeup • Race condition on the shared variable: count • Buffer is empty and consumer reads the counter as value 0. But before consumer can make the sleep() call, CPU switches to producer. Producer inserts an item, sets counter to 1 and sends a wakeup call to consumer. However, consumer is not sleeping yet, the wakeup signal is lost! • Now CPU switches back to consumer and it finally makes the sleep() call- consumer is asleep now. • Producer will fill up the buffer sooner or later, and it goes to sleep as well. • Both are sleeping!

  19. Semaphores • Two atomic operations: down and up • Suppose s is a semaphore • down(&s):s--; if s < 0 then sleep • up(&s):s++; if s <= 0 then wake up one of the processes blocked by down operation on s. • up operation never blocked! • What’s the value of s now? Don’t know • Can only be accessed by the two operations after initialization.

  20. Atomic Operations • Both down and up are as a single, indivisible atomic actions • Value < 0 indicates some process sleeping • Solve the lost-wakeup problem (why?) • How to implement these atomic operations? • Disable all interrupts • Use TSL instruction

  21. Use of Semaphores • Mutual exclusion • Semaphore s is initialized to 1. • Call down(&s) before enter critical region • Call up(&s) after leave critical region • Can be used for buffer in Producer-Consumer problem • Synchronization • Guarantee certain event sequences do or do not occur • E.g., the Producer stops running when the buffer is full.

  22. #define N 100 // number of slots in the buffer semaphore mutual = 1; // controls access to critical region semaphore empty = N; // counts empty buffer slots semaphore full = 0; // counts full buffer slots void producer(void){ int item; while (TRUE){ item = produce_item(); // generate something to put in buffer down(&empty); // decrement empty count down(&mutual); // enter critical region insert_item(item); // put new item in buffer up(&mutual);// leave critical region up(&full);// increment count of full slots } } void consumer(void){ int item; while (TRUE){ down(&full);// decrement full count down(&mutual); // enter critical region item = remove_item(); // take item from buffer up(&mutual);// leave critical region up(&empty);// increment count of empty slots } } Producer-Consumer using Semaphores

  23. Mutexes: Binary Semaphores • Achieve mutual exclusion • Two states: unlocked (0) / locked (1) • Two operations: mutex_lock(&m) and mutex_unlock(&m) • For a process • Call mutex_lock before entering critical region • Call mutex_unlock after leaving critical region • Can be implemented in user space with TSL instruction.

  24. Implementation of Mutex mutex_lock: TSL REGISTER, MUTEX | copy mutex to register and set mutex to 1 CMP REGISTER, #0 | was mutex zero? JZE ok | if it was zero, mutex was unlocked, so return CALL thread_yield| mutex is busy; schedule another thread JMP mutex_lock | try again latter ok: RET | return to caller; critical region entered mutex_unlock: MOV MUTEX, #0 | store a zero in mutex RET | return to caller Notice: thread_yield is used. Busy waiting does not work here. (Why?)

  25. Problems with Mutual Exclusion • Diskette and CD-Rom protected by mutexes • Process A: got diskette, waiting CD-Rom • Process B: got CD-Rom, waiting diskette • A deadlock! Blocked forever • Programming with semaphores or mutexes is tricky

More Related