02.2 Basic Concepts
02.2 Basic Concepts
Kostis Sagonas
[email protected]
int x = 0;
int y = x+1; int z = x+1;
printf("%d", y); printf("%d", z);
int x = 0;
int y = x+1; int z = x+1;
printf("%d", y); printf("%d", z);
The program will output “1” followed by another “1”. (It can’t output
anything else because printf is thread-safe. More on that later.)
Note that the two tasks may execute on different processors, or even on
different computers. Shared memory provides an abstraction from the
actual hardware.
However, writing correct code that uses shared memory can be very
tricky. We’ll now discuss some of the challenges.
int x = 0;
x = 1; printf("%d", x);
int x = 0;
x = 1; printf("%d", x);
(Actually, the program contains a data race. Depending on your hardware and
programming language, it may not output “0” or “1” after all: it could print a
different value or even crash. More on that soon.)
Race conditions easily lead to program bugs when the programmer did not
anticipate all possible executions.
if (check(x)) { act(x); }
1. Read a variable.
2. Compute a new value (that depends on the value read).
3. Update the variable.
P0 : P1 :
flag_0 = true; flag_1 = true;
while (flag_1) { while (flag_0) {
if (turn != 0) { if (turn != 1) {
flag_0 = false; flag_1 = false;
while (turn != 0) { while (turn != 1) {
// busy wait // busy wait
} }
flag_0 = true; flag_1 = true;
} }
} }
// critical section // critical section
... ...
turn = 1; turn = 0;
flag_0 = false; flag_1 = false;
Dekker’s algorithm (ca. 1962) was the first algorithm to solve the mutual
exclusion problem, using only shared memory for communication.
While too little synchronization leads to race conditions, too much (or
improper) synchronization likewise causes problems.
When one task is executing its critical section, other tasks that want to
begin executing their critical sections must wait.
A deadlock occurs when two (or more) tasks are waiting for each other.
A livelock is similar to a deadlock (two or more tasks are waiting for each
other), but the tasks involved keep changing their state, without making
proper progress.
In practice, lifelocks occur less often than deadlocks, but are somewhat
harder to detect.
Fairness means that as long as the system is making progress, a task that
is waiting for a resource will be granted the resource eventually. (However,
there is not necessarily a fixed upper bound on the waiting time.)
A data race occurs when two (or more) tasks attempt to access the same
shared memory location,
at least one of the accesses is a write, and
the accesses may happen simultaneously.
int x = 0;
x = 1; printf("%d", x);
Memory
http://en.wikipedia.org/wiki/Distributed_memory