



































Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
An introduction to the critical-section problem, its objectives, background, and various solutions. It covers both software and hardware approaches, including peterson's solution, synchronization hardware, semaphores, monitors, atomic transactions, and more. The document also discusses race conditions and their significance in concurrency.
Typology: Slides
1 / 43
This page cannot be seen from the preview
Don't miss anything!




































ļ Concurrency can be viewed at different levels:
ļ¼ multiprogramming ā interaction between multiple processes running on one CPU (pseudo-parallelism)
ļ¼ multithreading ā interaction between multiple threads running in one process
ļ¼ multiprocessors ā interaction between multiple CPUs running multiple processes/threads (real parallelism)
ļ¼ multicomputers ā interaction between multiple computers running distributed processes/threads
ā the principles of concurrency are basically the same in all of these categories
Process Interaction & Concurrency
Software
view
Hardware
view
Multithreaded shopping diagram and possible outputs
./multi_shopping grabbing the salad...
grabbing the milk... grabbing the apples... grabbing the butter... grabbing the cheese...
./multi_shopping grabbing the milk... grabbing the butter... grabbing the salad...
grabbing the cheese... grabbing the apples...
Molay, B. (2002) Unix/Linux Programming (1st Edition). Understanding
ļ Insignificant race condition in the shopping scenario
ļ¼ there is a ā race condition ā if the outcome depends on the order of the execution
Race Condition
CPU
CPU
ļ Insignificant race condition in the shopping scenario
ļ¼ the outcome depends on the CPU scheduling or āinterleavingā of the threads (separately, each thread always does the same thing)
./multi_shopping grabbing the salad... grabbing the milk... grabbing the apples... grabbing the butter... grabbing the cheese...
./multi_shopping grabbing the milk... grabbing the butter... grabbing the salad... grabbing the cheese... grabbing the apples...
Race Condition
char chin, chout;
void echo() { do { chin = getchar(); chout = chin; putchar(chout); } while (...); }
char chin, chout;
void echo() { do { chin = getchar(); chout = chin; putchar(chout); } while (...); }
./echo Hello world! Hello world!
Single-threaded echo Multithreaded echo (lucky)
./echo Hello world! Hello world!
1 2 3
4 5 6 lucky CPU scheduling
ļ
ļ Significant race conditions in I/O & variable sharing
Race Condition
char chin, chout;
void echo() { do { chin = getchar(); chout = chin; putchar(chout); } while (...); }
./echo Hello world! Hello world!
Single-threaded echo
char chin, chout;
void echo() { do { chin = getchar(); chout = chin; putchar(chout); } while (...); }
ļ Significant race conditions in I/O & variable sharing
1 5 6
2 3 4 unlucky CPU scheduling
ļ
Multithreaded echo (unlucky)
./echo Hello world! ee....
Race Condition
ļ Significant race conditions in I/O & variable sharing
ļ¼ in this case, replacing the global variables with local variables did not solve the problem
ļ¼ we actually had two race conditions here: ļ§ one race condition in the shared variables and the order of value assignment ļ§ another race condition in the shared output stream:
ā generally, problematic race conditions may occur whenever resources and/or data are shared ļ§ by processes unaware of each other or processes indirectly aware of each other
Race Condition
while (true) {
/* Produce an item / while (((in = (in + 1) % BUFFER SIZE) == out) ; / do nothing -- no free buffers */ buffer[in] = item; in = (in + 1) % BUFFER SIZE;
}
while (true) { while (in == out) ; // do nothing -- nothing to consume // remove an item from the buffer item = buffer[out]; out = (out + 1) % BUFFER SIZE; return item; }
register1 = count register1 = register1 + 1 count = register
register2 = count register2 = register2 - 1 count = register
ļ How to avoid race conditions?
ļ¼ find a way to keep the instructions together ļ¼ this means actually... reverting from too much interleaving and going back to āindivisible/atomicā blocks of execution!!
thread A
thread B
chin='H'
chin='e'
putchar('e')
chout='e' putchar('e')
(a) too much interleaving may create race conditions
(b) keeping āindivisibleā blocks of execution avoids race conditions
thread A
thread B
chin='H'
chin='e'
putchar('H')
chout='e' putchar('e')
Race Condition
enter critical region?
exit critical region
enter critical region?
exit critical region
ļ¼ critical regions can be protected from concurrent access by padding them with entrance and exit gates o a thread must try to check in, then it must check out
ļ We need mutual exclusion from critical regions
void echo() { char chin, chout; do {
chin = getchar(); chout = chin; putchar(chout);
} while (...); }
void echo() { char chin, chout; do {
chin = getchar(); chout = chin; putchar(chout);
} while (...); }
Critical Regions
do {
entry section
critical section
exit session
remainder section
} while (TRUE);