Module 2: Synchronization Flashcards
(45 cards)
Heap and stack memories
- Reference to an object + value type data is saved in the Stack. EX: the object ‘account’
- Object’s data is saved in the Heap. EX: ‘5000, 0.5, 12’ is saved in ‘account’.
- Every thread has its own program counter & needs its own calls stack.
How do threads communicate?
- Through shared variables
- Through message passing / method calls
Shared resources
- EX: Instance variables
- Multiple threads run the same method, work w/ diff values saved in the same variable & produce wrong results.
Local variables as a shared resource?
- Every thread executing a method remembers the values stored in the local variables.
- When running the method at the same time = output correct.
Local object reference as a shared resource?
- The reference itself is placed on the stack but object data is on the heap.
- Method is thread safe; every thread creates own instance of the object, the reference to the local object will be placed on the thread’s local stack.
- Just don’t make the local object available to another thread.
Context switch
- Process of storing the state of a process or thread, so that it can be restored and resume execution at a later point.
- Threads may race to update & save the variable.
Interleave
- Operation can consist of multiple steps.
- EX: k++;
1. Retrieve current value of k.
2. Increment value by 1, k = k+1
3. Store the incremented value back in k - Threads can overwrite each other by reading the initial value of k instead of the updated version.
Atomic operation
- Performs completely w/o interleaving (i.e interference)
- Can’t stop in the middle. Either happens fully or doesn’t at all.
- k++; done completely by one thread before another accesses k.
Thread Interference
- Condition when more than one thread, executing simultaneously, accesses the same piece of data.
- Caused by interleaving
- Data may get corrupted
- Occurs when the code is not THREAD SAFE.
Thread safe
- Code is safe to call by multiple threads simultaneously.
- Non-interference: safety property. Guarantees that atomic action in a thread does not alter a shared resource.
Avoiding thread interference
- Locks
- Const, readonly
- Thread-local variables
- Atomic operations (Mutual Exclusion)
Race condition
- Threads race through the critical secion
- Sharing data & resources => Reading/Writing can occur in the wrong order. Erroneous output & corrupt data.
Synchronization
- Process of making threads work in a way to ensure that shared data and resources are used safely.
- Possible interleaving is restricted.
- EX: locks, mutex, semaphores, monitors, condition variables.
Sync Patterns
- Writer-Reader
- Producer-Consumer (bounded buffer)
Mutual Exclusion
- Only one thread is allowed to be in its critical region at a certain time.
- ME is a mechanism that ensures this.
Condition sync
- Wait, Pulse, PulseAll
- Signal a condition, process sets a shared variable
- One thread waits for an event signaled from another thread
- Wait for a condition to become true (called ‘busy waiting’)
Critical Section
- Sequences of instructions that may get incorrect results if executed simultaneously
- Usually accesses shared variables
- Must be protected!!!
Four Requirements for a solution
- Mutual Exclusion
- Progress
- Fairness
- No assumption on performance
Requirement for solution: Mutual Exclusion
Only one thread in the critical section at a time.
Requirement for solution: Progress
No dead/livelock. When no thread is in the CS, any thread that wants to enter should do so without delay.
Requirement for solution: Fairness
No starvation. A thread shouldn’t wait indefinitely to enter the CS. => Bounded Wait (upper bound on nr of times a thread is allowed to enter its CS while another thread is waiting).
Requirement for solution: No assumption on performance
Requirements must be met with any nr of CPUs with any relative speed. Overhead of entering & exiting should be small.
What is a “lock”?
object lockObj = new object();
lock (lockObj)
- Simple. Ensures Mutual Exclusion but deadlock, livelock, starvation can occur.
- Lock is aquired by running thread when a statement is executed
- Automatically released at the end of the lock-block
Lock states
- Held (locked) - lock is in use
- Not Held (unlocked) - lock is not in use