Challenges of Concurrent Programming
Sharing of Resources
- A resource can be a property or an object, memory in general, a network device, a file, etc.
- Anything you share between multiple threads is a potential point of conflict
Race Condition
In order to prevent this, multiple threads need to access shared resources in a mutually exclusive way.
Mutual Exclusion
- Mutual exclusive access means that only one thread at a time gets access to a certain resource.
- In order to ensure this, each thread that wants to access a resource first needs to acquire a mutex lock on it.
- Once it has finished its operation, it releases the lock
Dead Locks
A dead lock occurs when multiple threads are waiting on each other to finish and get stuck.
Race Condition
- Race conditions are caused by shared mutable state.
- It occurs when two or more threads try to change it at the same time.
- OS can swap between threads at any time, you can't guarantee the order in which the threads will attempt to access the shared data
Problems often occur when one thread does a "check-then-act" and another thread does something to the value in between the "check" and the "act".
A critical section is a piece of code that must not be executed concurrently, that is, from two threads at once. This is usually because the code manipulates a shared resource such as a variable that can become corrupt if it’s accessed by concurrent processes.
if (x == 5) { // The "Check"
y = x * 2; // The "Act"
// If another thread changed x in between "if (x == 5)" and "y = x * 2" above,
// y will not be equal to 10.
}
The point being, y could be 10, or it could be anything, depending on whether another thread changed x in between the check and act. You have no real way of knowing.
Prevent Race Condition In order to prevent race conditions from occurring, you would typically put a lock around the shared data to ensure only one thread can access the data at a time. This would mean something like this:
// Obtain lock for x
if (x == 5) {
y = x * 2; // Now, nothing can change x until the lock is released. Therefore y = 10
}
// release lock for x