CST-334 Week 6
This week I learned more about conditional variables, semaphores, and how to write code using semaphores. One of the solutions we came up with was the polling solution. In this case, we want to occasionally read from the shared resource. An example of this could look something like:
static int some_value = 0;
void* read(void* thread) {
while (1) {
sleep(1);
some_value = get_value();
}
}
void* api(void* thread){
while (1) {
if (some_vaue != old_value) {
old_value = some_value;
}
}
}
In this example, the shared resource (some_value) is being constantly read inside our loop. This ensures that we can run some condition whenever the value store inside our variable changes. However, this introduces some problems. This solution is inefficient as it is constantly running to check to the value stored inside some_value, causing the CPU to waste resources. A better solution would be to put the thread to sleep until the value of our shared resource changes. This is referred to as the notification solution. In our C programs, we can setup this solution by using pthread_cond_signal(cond_var) and pthread_cond_wait(cond_var, mutex);
In our api function we can use the wait condition, which will put the thread to sleep and release any locks that it has acquired. In our read function, we can add a signal condition after we change the value of some_value, causing the api thread to wake up and read the new value stored inside some_value.
With multi-threaded programs, the execution path of a program can be different each time it is ran without some form of protection. While locks and conditional variables are a viable solution, there is another solution that does not use conditional variables or locks: semaphores. Semaphores are essentially an integer value that can be incremented or decremented. When a semaphore is incremented (signaled), any thread that is waiting will be unblocked. When a semaphore is decremented (waiting), the thread will block itself if the value of the semaphore is less than 0.
Semaphores can be beneficial, as they can provide less overhead and avoid certain deadlocks when compared to locks and conditional variables. However, semaphores can be more difficult to debug and work with as they are not as clear as locks and conditional variables.
One thing I found that was interesting, was that deadlocks seemed to be very similar to deadlocks that can occur in database systems. In concurrent programs, a thread may be holding a resource while it is waiting for another recourse that is being held by a thread that is waiting for them to release their resource. In database systems, we can use transactions to ensure data integrity, but deadlocks can occur that are very similar to deadlocks that can occur in operating systems.
Comments
Post a Comment