1 / 34

Chapter 6: Process Synchronization

Chapter 6: Process Synchronization. Objectives. Understand The Critical-Section Problem And its hardware and software solutions. Consumer-Producer Problem. Classic example of process coordination Two processes sharing a buffer One places items into the buffer (producer)

jmerry
Download Presentation

Chapter 6: Process Synchronization

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. Chapter 6: Process Synchronization

  2. Objectives • Understand • The Critical-Section Problem • And its hardware and software solutions

  3. Consumer-Producer Problem • Classic example of process coordination • Two processes sharing a buffer • One places items into the buffer (producer) • Must wait if the buffer if full • The other takes items from the buffer (consumer) • Must wait if buffer is empty • Solution: Keep a counter on number of items in the buffer

  4. Producer while (true) { /* produce an item in nextProduced */ while (count == BUFFER_SIZE) ; // do nothing buffer [in] = nextProduced; in = (in + 1) % BUFFER_SIZE; count++; }

  5. Consumer while (true) { while (count == 0) ; // do nothing nextConsumed = buffer[out]; out = (out + 1) % BUFFER_SIZE; count--; /* consume the item in nextConsumed */ } What can go wrong with this solution?

  6. Race Condition • count++ could be implemented a • register1 = count • register1 = register1 + 1 • count = register1 • count-- could be implemented as • register2 = count • register2 = register2 - 1 • count = register2 • Consider this execution interleaving with “count = 5” initially: S0: producer execute register1 = count {register1 = 5}S1: producer execute register1 = register1 + 1 {register1 = 6} S2: consumer execute register2 = count {register2 = 5} S3: consumer execute register2 = register2 - 1 {register2 = 4} S4: producer execute count = register1 {count = 6 } S5: consumer execute count = register2 {count = 4}

  7. Race Condition • Occurs when multiple processes manipulate shared data concurrently and the result depends on the particular order of manipulation • Data inconsistency may arise • Solution idea • Mark code segment that manipulates shared data as critical section • If a process is executing its critical section, no other processes can execute their critical sections • More formally, any method that solves the Critical-Section Problem must satisfy three requirements …

  8. Critical-Section Problem • Mutual Exclusion - If process Pi is executing in its critical section, then no other processes can be executing in their critical sections • Progress - If no process is executing in its critical section and there exist some processes that wish to enter their critical section, then the selection of the processes that will enter the critical section next cannot be postponed indefinitely • Bounded Waiting - A bound must exist on the number of times that other processes are allowed to enter their critical sections after a process has made a request to enter its critical section and before that request is granted • Assumptions • Each process executes at a nonzero speed • No restriction on the relative speed of the N processes

  9. Peterson’s Solution • Software solution; no hardware support • Two process solution • Assume that the LOAD and STORE instructions are atomic; that is, cannot be interrupted (may not always be true in modern computers) • The two processes share two variables: • int turn; • Boolean flag[2]; • turn indicates whose turn it is to enter the critical section • The flag array indicates whether a process is ready to enter the critical section • flag[i] = true ==> process Pi is ready

  10. Algorithm for Process Pi while (true) { flag[i] = TRUE; turn = j; while (flag[j] && turn == j) ; CRITICAL SECTION flag[i] = FALSE; REMAINDER SECTION } Does this algorithm satisfy the three requirements?

  11. Synchronization Hardware • Uniprocessors – could disable interrupts • Currently running code would execute without preemption • Generally too inefficient on multiprocessor systems • Operating systems using this not broadly scalable • Many systems provide hardware support for critical section code  more efficient and easier for programmers • Modern machines provide special atomic hardware instructions • Atomic = non-interruptable • Either test memory word and set value • Or swap contents of two memory words

  12. TestAndndSet Instruction • Definition: boolean TestAndSet (boolean *target) { boolean rv = *target; *target = TRUE; return rv; }

  13. Solution using TestAndSet • Shared boolean variable lock, initialized to false while (true) { while ( TestAndSet (&lock ) ) ; /* do nothing // critical section lock = FALSE; // remainder section } Does this algorithm satisfy the three requirements? NO. A process can wait indefinitely for another faster process that is accessing its CS. Check Fig 6.8 for a modified version.

  14. Swap Instruction • Definition: void Swap (boolean *a, boolean *b) { boolean temp = *a; *a = *b; *b = temp: }

  15. Solution using Swap • Shared boolean variable lock initialized to FALSE; • Each process has a local boolean variable key while (true) { key = TRUE; while ( key == TRUE) Swap (&lock, &key ); // critical section lock = FALSE; // remainder section }

  16. Semaphore • Much easier to use than hardware-based solutions • Semaphore S – integer variable • Two standard operations modify S: • wait() • signal() • These two operations are indivisible (atomic)

  17. Semaphore Operations wait (S) { while (S <= 0) ; // no-op, called busy waiting, spinlock S--; } signal (S) { S++; } • Later, we will see how to implement these operations with no busy waiting

  18. Semaphore Usage • Countingsemaphore – can be any integer value • Binary semaphore – can be 0 or 1, (also known as mutexlocks) • Mutual exclusion Semaphore mutex; // initialized to 1 wait (mutex); Critical Section signal (mutex); • Process synchronization: S2 in P2 should be executed after S1 in P1 P1: S1; signal (sem); P2: wait (sem); S2; • Control access to a resource with finite number of instances • Example: producer-consumer problem with finite buffer

  19. Semaphore Implementation with no Busy waiting • With each semaphore there is an associated waiting queue. Each entry in a waiting queue has two data items: • value (of type integer) • pointer to next record in the list • Two operations: • block – place the process invoking the operation on the appropriate waiting queue. • wakeup – remove one of the processes in the waiting queue and place it in the ready queue.

  20. Semaphore Implementation with no Busy Waiting wait (S) { value--; if (value < 0) { add this process to waiting queue block(); } } signal (S) { value++; if (value <= 0) { /*if some processes are waiting*/ remove a process P from waiting queue wakeup(P); } }

  21. Semaphore Implementation • Must guarantee that no two processes can execute wait and signal on the same semaphore at the same time • Thus, implementation becomes the critical section problem where the wait and signal code are placed in the critical section, and protected by • Disabling interrupts (uniprocessor systems only) • Busy waiting or spinlocks (multiprocessor systems) • Can not disable interrupts on all processors (too costly and degrades performance) • Well, why we do not do the above in applications anyway? • Applications may spend long (and unknown) amount of time in critical sections, unlike the kernel which spends a short and known beforehand time in the critical section (~ ten instructions)

  22. Deadlock and Starvation • Deadlock – two or more processes are waiting indefinitely for an event that can be caused by only one of the waiting processes • Let S and Q be two semaphores initialized to 1 P0P1 wait (S); wait (Q); wait (Q); wait (S); . . . . . . signal (S); signal (Q); signal (Q); signal (S); • Starvation – indefinite blocking. A process may never be removed from the semaphore queue in which it is suspended.

  23. Classical Problems of Synchronization • Bounded-Buffer Problem • Readers and Writers Problem • Dining-Philosophers Problem • These problems are usually used to test newly proposed synchronization schemes

  24. Bounded-Buffer Problem • N buffers, each can hold one item • Semaphore mutex initialized to the value 1 • Semaphore full initialized to the value 0 • Semaphore empty initialized to the value N

  25. Bounded Buffer Problem (Cont.) • The structure of the producer process while (true) { // produce an item wait (empty); wait (mutex); // add the item to the buffer signal (mutex); signal (full); }

  26. Bounded Buffer Problem (Cont.) • The structure of the consumer process while (true) { wait (full); wait (mutex); // remove an item from buffer signal (mutex); signal (empty); // consume the removed item }

  27. Dining-Philosophers Problem • Shared data • Bowl of rice (data set) • Semaphore chopstick [5] initialized to 1

  28. Dining-Philosophers Problem (Cont.) • The structure of Philosopher i: While (true) { wait ( chopstick[i] ); wait ( chopStick[ (i + 1) % 5] ); // eat signal ( chopstick[i] ); signal (chopstick[ (i + 1) % 5] ); // think }

  29. Be Careful When You Use Semaphores • Some common problems … • signal (mutex) …. wait (mutex) • Multiple processes can access CS at the same time • wait (mutex) … wait (mutex) • Processes may block for ever • Omitting of wait (mutex) or signal (mutex) (or both)

  30. Synchronization Examples • Windows XP • Linux • Pthreads

  31. Windows XP Synchronization • Uses interrupt masks to protect access to global resources on uniprocessor systems (inside kernel) • Uses spinlocks on multiprocessor systems • Also provides dispatcher objects for thread synchronization outside kernel, which can act as mutexes, semaphores, or events (condition variables)

  32. Linux Synchronization • Linux: • disables interrupts to implement short critical sections (on single processor systems) • Linux provides: • semaphores • Spinlocks (on SMP)

  33. Pthreads Synchronization #include <pthread.h> pthread_mutex_t mutex; pthread_mutex_init(&mutex, null); pthread_mutex_lock(&mutex); pthread_mutex_unlock(&mutex); #include <semaphore.h> sem_t sem; sem_init(&sem, 0, 5); sem_wait(&sem); sem_post(&sem); • Pthreads API is OS-independent • It provides: • mutex locks • condition variables • extensions include: • semaphores • read-write locks • spin locks • May not be portable

  34. Summary • Processor Synchronization • Techniques to coordinate access to shared data • Race condition • Multiple processes manipulating shared data and result depends on execution order • Critical section problem • Three requirements: mutual exclusion, progress, bounded waiting • Software solution: Peterson’s Algorithm • Hardware support: TestAndSet(), Swap() • Busy waiting (or spinlocks) • Semaphores: • Not busy waiting • wait(), signal() must be atomic  moves the CS problem to kernel • Some classical synchronization problems • Consumer-producer • Dining philosopher • Readers-writers • Examples • Win XP, Linux, Pthreads

More Related