Week 5 - Concurrency

This week the module touched upon the topic of concurrency in regards to processes and threads. In the previous database systems course taken before this class we touched upon some aspects of concurrency with database transactions, exploring the concepts of deadlocking and atomicity.
 

After exploring the readings in the OSTEP book I found a great deal of similarities between these two utilizations of concurrency. The introduction to concurrency for operating systems begins by understanding that a process itself is a single thread, as the process itself contains one stack. This single process executes a task normally but with multiple threads we can split the tasks and continue executing them simultaneously to get the results much faster. Something to note is that the thread may contain one stack per thread. From the introductory chapter, I have learned that a thread itself shares the same address space and accesses the same data as the process, but in a way acts as though it's another process. The reason why threads were introduced was due to increasing speed in execution, using the threads can split the work allowing the program to finish much faster. The second reason is that if a program gets stuck waiting for I/O, while this is being stuck waiting and wasting CPU, we could potentially execute something else in order to not waste any time. In order to create a thread we were introduced with the thread creation API introducing some function calls such as Int pthread_create, pthread_join, and locks/mutex creation with int pthread_mutex_lock and int pthread_mutex_unlock.
 

The creation of threads can lead to situations that are non-deterministic, meaning that we may have two threads executing at the same time but may yield different results or behave differently in different runs. An example of this is when two threads share the same critical section, or a piece of code that accesses a shared variable, this could be a global variable, but both are accessing it and changing it through its threads. In this situation they shouldn’t be able to do this and should be mutually exclusive, meaning that they should have one using the critical section while the other is prevented from doing so until it gets its chance. A way to solve this situation is through utilizing mutex or also known as locks. The mutex will allow each thread a chance to use the critical section, allowing them to not step over each other's execution. The problem that comes with adding the mutex is the speed of execution and the chance that interrupts may happen in the middle of lock and potentially causing starvation to the one not holding the lock. Ways to solve this is through different lock creation algorithms that utilize hardware calls such as test-and-set, compare-and-swap, fetch-and-add, and loaded links and conditionals. Overall the introduction to concurrency in processes has been a bit difficult to understand at first. Though after going through some of the demo codes and re-reading the OSTEP, I’ve gotten more interested in the topic and hope to learn a bit more about it, especially the coordination between threads, where a thread may need something from the other and has to wait for the other thread's completion.

Comments