The sixth week of CST 334 discussed semaphores and common multithreading pitfalls.
Semaphores are a general-purpose synchronization structure – usually implemented with a lock, a condition variable, and a counter. There are three main functions that interact with semaphores: sem_init, sem_wait, and sem_post.
- sem_init: Initializes the semaphore’s counter to the given value.
- sem_wait: Decrements the semaphore’s counter. If the counter is subsequently 0 or greater, the call instantly returns. If the counter is subsequently less than 0, the call suspends the thread’s execution until later.
- sem_post: Increments the semaphore’s counter. If there are one or more threads waiting on the semaphore, wake one.
Common multithreading pitfalls include:
- Atomicity-Violations: Instructions that were assumed to behave atomically do not. This is caused by a critical section not properly utilizing synchronization primitives. For example, if two threads attempt to increment a counter without first acquiring a lock that guards the counter, some increment operations can be lost.
- Order-Violations: The execution of a set of instructions differs from the expected order. For example, a child thread uses a resource that is initialized in the parent thread after the child is created, yet the scheduler decides to run the child immediately after it is created, before the parent has initialized the resource.
- Deadlock Conditions: A deadlock is when multiple threads are stuck waiting on each other to release some resource. Deadlocks can occur when all of the following criteria are met:
- Mutual exclusion: Threads exclusively own resources.
- Hold-and-wait: Threads hold certain resources while waiting to acquire other additional resources.
- No preemption: Threads cannot have their ownership of resources removed by other threads.
- Circular wait: There exists multiple threads, where each thread in the chain holds a resource that the next thread is waiting to acquire.
No comments:
Post a Comment