Week 5 – CST– 334 Operating System

Module 5 – Concurrency Introduction

This week we covered an introduction to concurrency. So far, we have studied single threaded programs. Programs can also have multiple threads of execution. A process for example, can fork a child but parent and child do not share memory because they have their own copies of code and data in memory. A process can also create multiple threads which share the same address space and can use global variables to communicate which use less memory. Each thread has its own program counter and stack.

The advantage of using threads is parallelism, this means that a single process can use multiple CPU cores in parallel to complete tasks. The disadvantage when using threads comes in the form of a race condition. A race condition happens when multiple threads access a section of code that has shared variables. These sections of code are called critical sections. Multiple threads entering this section causes unpredictable results. In order to avoid race conditions, programmers must use locks to protect critical sections.

Locks are meant to allow only one thread at a time to access a critical section. Once done, the thread gives up the lock and another thread will hold the lock to gain access into the critical section. While a thread has a lock in a critical section, other threads can spin until the lock becomes available. Spinning means the thread is stuck in a while loop until the lock is released. Spinning is considered inefficient because the thread wastes an entire time slice just checking a value that indicates whether the lock is available. Other alternatives threads can use are wait, sleep, or yield the CPU which moves the thread from a running state to the ready state.

Lastly, we learned about condition variables wait and signal. These are used in situations where a thread wishes to check whether a condition is true before continuing its execution. The text explains condition variables with the producer/ consumer problem. A problem where producers produce data items and put them on a buffer. Consumers grab the data items from the buffer to consume them. The producer threads wait on the condition empty, and signal fill when they are done executing. The consumer threads wait on fill and signal empty when done executing. This prevents threads from waking up the wrong type of threads. An example of this problem is a multi-threaded web server. Producer threads put HTTP requests into a work queue and consumer threads take the requests out of the queue and process them.

Comments

Popular posts from this blog