Download Process Synchronization - Operating System - Lecture Slides and more Slides Computer Science in PDF only on Docsity!
Chapter 6:
Process
Synchronization
1
2
What is the output?
#include <pthread.h> #include <stdio.h> #include <stdlib.h>
void *runner(void *param); // the child thread
int main (int argc, char *argv[]) { pthread_t tid; // thread ID pthread_attr_t attr; // set of thread attributes // get the def ault attributes if (pthread_attr_init(&attr) != 0) { fprintf(stderr, "Error: Could not get thread attributes! \n"); exit(1); } // create the thread pthread_create(&tid, &attr, runner, NULL); printf("this is some output from "); fflush(stdout); printf("the parent thread \n"); fflush(stdout); }
void *runner(void *param) { printf("dolphins are large "); fflush(stdout); printf("brained mammals \n"); fflush(stdout); pthread_exit (0); }
this is some output from dolphins are large brained mammals the parent thread
this is some output from the parent thread
2 separate runs of the same program:
4
Therac-
- Between June 1985 and January 1987, some
cancer patients being treated with radiation were
injured & killed due to faulty software
- Massive overdoses to 6 patients, killing 3
- Software had a race condition associated with
command screen
- Software was improperly synchronized!!
- See also
p. 340-341 Quinn (2006), Ethics for the Information Age
Nancy G. Leveson, Clark S. Turner, "An Investigation of the Therac-25 Accidents," Computer, vol. 26, no. 7, pp. 18-41, July 1993 http://doi.ieeecomputersociety.org/10.1109/MC.1993.
5
Chapter 6: Process
Synchronization
- Critical Section (CS) problem
- Partial solutions to CS problem
- Busy waiting
- Semaphores
- Atomicity
- Hardware methods for atomicity
- Multiple CPU systems
- Classic problems
- Bounded buffer, producer-consumer, readers-writers, dining philosophers
- Monitors
Critical Section
- N processes (P1, P2, …, PN) are accessing
shared data (e.g., RAM, or shared files).
- Access typically involves reads and writes to data
- The program code where shared data is accessed
in a process is the critical section of that process
- General Goal : ensure that only one of P1, P2, …, PN are in their critical sections at any particular time - Can loosen this requirement at times if processes are only reading the data
- Main requirements for entry/exit methods (see
p. 220 of text)
- Provide mutual exclusion
- Allow progress
- Have bounded waiting
Main requirements for entry/exit
methods (see p. 220 of text)
- mutual exclusion
- If process P i is executing in its critical section, then no other process can be executing in its critical sections
- progress
- If no process is executing in its critical section and some processes wish to enter their critical sections, then only those processes that are not executing in their remainder sections can participate in deciding which will enter its critical section next, and this selection cannot be postponed indefinitely
- bounded waiting
- There exists a bound, or limit, 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 8
10
Partial Solution 1 to Critical Section Problem
// thread 0
do {
while (turn != 0) {}
// c. s.
turn = 1;
// remainder code
} while (true);
// thread 1
do {
while (turn != 1) {}
// c. s.
turn = 0;
// remainder code
} while (true);
// global variable // initialized before threads start int turn = 0; // number of thread that can enter CS next
Do we have mutual exclusion? Progress? Bounded waiting?Docsity.com
11
Partial Solution 2 to Critical Section Problem
// thread 0
do {
flag[0] = true;
while (flag[1]) {}
// c. s.
flag[0] = false;
// other code
} while (true);
// thread 1
do {
flag[1] = true;
while (flag[0]) {}
// c. s.
flag[1] = false;
// other code
} while (true);
// initialization // flag[ i ] set if thread i wants access to CS bool flag[2] = {false, false};
Do we have mutual exclusion? Progress? Bounded waiting?Docsity.com
In Summary
- We have a solution to the critical section
problem
- uses few assumptions (e.g., assignment is
atomic)
- However, there are more general, typical
solutions
13
Issues with this critical section solution
- Complex code
- It’s hard to figure out if the code is correct
- Busy waiting
- Busy wait (aka. polling ): In a loop,
continuously checking the value of variables
- These processes are doing a busy wait until
allowed into critical section
- Busy waiting is not the same as a process being
blocked. Why?
- Threads actively take CPU cycles when waiting
for other threads to exit from critical section
Busy Wait Loop
16
“terminated” is not used correctly here; this is not thread cancellation!
17
Complex Code: Think About Critical
Section (CS) Problem More Abstractly
operations:
enter()
- perform operations needed so only current thread can access CS
exit()
- Perform operations to enable other threads to access CS
do {
enter();
// CS
exit();
// other code
} while (true);
Further Issue : What if we have multiple processes trying to enter? Or what if we have multiple critical sections? Docsity.com
19
Semaphores: With Busy Waiting
- Traditionally enter() is called “P” (or “wait”) exit() is called “V” (or “signal”)
- Data type of the parameter is called semaphore
semaphore (int value );
- Semaphore constructor
- Integer value
- number of processes that can enter critical section without waiting; often initialized to 1.
void P(semaphore *S);
while (S->value <= 0) {}; Decrement S->value;
void V(semaphore *S);
Increment S->value;
Often not a practical implementation: Uses a busy wait Docsity.com
20
Need ‘Atomic’ Operations
- Need some level of indivisible or “atomic”
sequences of operations
- E.g., when an operation runs, it completes without another process executing the same code, or the same critical section
- In P , we must test & decrement value of
semaphore in one step
- e.g., with semaphore value of 1, don’t want two processes to test value of S, find that it is > 0, and both decrement and value of S
- Plus, increment operation must be atomic