Race Condition
int global_var = 0;
global_var increment can take
several instruction cycles!
void incTask(void *parameters) {
while(1) {
global_var:
global_var++;
0
}
1
}
2
3
void main() {
3
startTask1(incTask, “Task 1”);
4
startTask2(incTask, “Task 2”);
5
sleep();
5
}
Task A
Global
Variable
Task B
Race Condition
int global_var = 0;
global_var increment can take
several instruction cycles!
void incTask(void *parameters) {
while(1) {
global_var:
global_var++;
0
}
1
}
2
3
void main() {
3
startTask1(incTask, “Task 1”);
4
startTask2(incTask, “Task 2”);
5
sleep();
5
}
Global
Task A Task B
Variable
Get value from memory 0
Increment value
Write value to memory 1
1 Get value from memory
Increment value
2 Write value to memory
Get value from memory 2
2 Get value from memory
Increment value
3 Write value to memory
Increment value
Write value to memory 3 Uh-oh.
Protecting Shared Resources and Synchronizing Threads
● Queue: pass messages (data) between threads
● Lock: allows only one thread to enter the “locked” section of code
● Mutex (MUTual EXclusion): Like a lock, but system wide (shared by multiple
processes)
● Semaphore: allows multiple threads to enter a critical section of code
Task A Global Task B
Mutex
Variable
1 0
Check for and take mutex
0 0
Get value from memory
0 0
Check for and take mutex
0 0
Wait/yield
0 0
Increment value
0 0
Write value to memory
0 1
Give mutex
1 1
Check for and take mutex
0 1
Get value from memory
0 1
Increment value
0 1
Write value to memory
0 2
Give mutex
1 2