AdminDev Labs

Race Conditions


Listen Later

## Race Conditions

### Definition
- Two or more processes are reading or writing some shared data and the final result depends on who runs precisely when.

### Tanenbaum example (Printer daemon)
- Process enters name of file in spooler dir
- Printer daemon checks to see if file need printing
- Prints and removes names from spooler dir
- Spooler dir has 0 ... infinity
- Two shared variables, output, point at file to be printed
- in, points to free slot in spooler dir
- Proc A and B queue file for printing
- A reads in, stores slot 7 in variable
- Clock interrupt occurs
- B reads in, stores slot 7 in same variable
- B writes to slot 7, updates in to slot 8
- A writes to slot 7, erasing what B put there, updates in to slot 8
- Spooler dir now in sync
- B never receives output

### Golang example (Incrementing a counter)
- Proc 1 read counter 0
- Yield thread 0
- Increment counter 1
- Proc 2 read counter 0
- Yield thread 0
- Increment counter 1
- Proc 1 write counter 1
- Proc 2 write counter 1
- Proc 1 read counter 1
- Yield thread 1
- Increment counter 2
- Proc 2 read counter 1
- Yield thread 1
- Increment counter 2

### Go-isms
- go run -race main.go
- Don't communicate by sharing memory, share memory by communicating
- Passing on a channel the data structure or object.

### Avoiding Race Conditions
- No two processes may be simultaneously inside their critical regions.
- No assumptions may be made about speeds or the number of CPUs.
- No process running outside its critical region may block any process.
- No process should have to wait forever to enter its critical region.

### Mutal Exclusion
- While a process is busy updating shared memory no other process will attempt to enter shared memory space.
- Disabling interrupts (Single CPU)
- This approach is generally unattractive because it is unwise to give user processes the power to turn off interrupts.
- Lock variables
- Test the lock
- If 0 set to 1
- Before process can set 0 to 1, another process reads as 0
- The race now occurs if the second process modifies the lock just after the first process has finished its second check.
- Busy Waiting
- It should usually be avoided, since it wastes CPU time
- Mutual Exclusion Algorithm: G. L. Peterson
- Each process calls enter\_region
- Wait, if necessary, until safe to enter shared memory region
- Process calls leave\_region after done with shared memory

```
#define FALSE 0
#define TRUE 1
#define N 2 / * number of processes * /
int turn; / * whose turn is it? * /
int interested[N]; / * all values initially 0 (FALSE) * /

void enter region(int process); / * process is 0 or 1 * /
{

int other; / * 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) / * null statement * / ;
}

void leave region(int process) / * process: who is leaving * /
{
interested[process] = FALSE; / * indicate departure from critical region * /
}
```

...more
View all episodesView all episodes
Download on the App Store

AdminDev LabsBy Chris Kennedy