
Explain the components of a process, including its address space, code and data, global variables, and resources, and why process creation and interprocess communication incur substantial overhead.
Explore why expensive process creation can hinder performance by showing a web server cloning child processes to service many requests in parallel, and highlight the overhead.
Separate the concept of a process from its execution state to enable threads that share code, data, privileges, and resources while running different program logics.
Compare single threaded and multithreaded processes, showing how threads share code, data, and system resources within a process while each thread maintains its own registers, stack, and program counter.
Threads in the same process communicate via shared memory and global variables, avoiding system calls. They exploit hardware parallelism across cores and offer modular solutions with lower overhead than processes.
Explore the POSIX thread (pthreads) API for portable multithreading, including thread creation, synchronization, and linking with -lpthread on unix-like systems.
Create a new thread with pthread_create by passing a function and its argument, with default attributes, while the main thread continues and the OS schedules them in no guaranteed order.
Pass thread arguments by defining a structure for A and B, allocate it dynamically, cast to a void pointer for thread creation, and reclaim memory after use.
Use pthread_self to obtain a thread's own ID, and pthread_equal to compare thread IDs for correctness and portability in multi-threaded programs.
Explore how threads terminate in multithreading with four paths: thread function completion, pthread_exit, pthread_cancel, and process termination, and understand asynchronous, synchronous, and uncontrollable cancellation.
Use pthread_join to wait for a thread's termination by supplying its thread ID and optional void pointer for the return value; pass null if unused, and cancellation returns indicate termination.
Learn how pthreads return values using a void pointer, via pthread_exit or a return statement, avoid returning addresses of local variables, and why dynamic allocation enables retrieval with pthread_join.
Learn how thread join collects a terminated thread's return value to free resources, and how detach releases resources immediately, preventing future joins.
pthread_detach detaches a thread by thread id or pthread_self, returns zero on success, and reclaims resources immediately when the thread terminates; avoid detaching if you plan to join.
Learn correct thread joining to collect a return value and reclaim resources, preventing memory leaks when a thread terminates without being joined or detached.
Explore how global variables are shared across threads and why synchronization matters. Learn how per-thread data can be stored with p_keys_create to avoid cross-thread interference.
Explore concurrency basics by comparing deterministic in-thread execution with non deterministic interleavings across threads caused by scheduling and context switches, highlighting testing and debugging challenges.
Define concurrency and illustrate how multiple threads access shared memory, causing race conditions during queue updates; demonstrate how interleaving context switches can overwrite data and create gaps.
Investigate race conditions from concurrent thread reads and writes and learn how atomic operations ensure all-or-nothing execution, highlighting that many C++ statements are not atomic without operating system primitives.
Learn mutual exclusion, critical sections, and synchronization in concurrent programs. A two-roommate milk scenario shows how threads coordinate to avoid too little or too much milk.
Explains safety and liveness as key correctness properties in synchronization problems, using the milk example to show that safety prevents bad outcomes and liveness ensures progress, both required.
Using sticky notes to coordinate milk purchases, two threads may both leave notes and buy milk if preempted, causing the too much milk problem and violating the safety property.
Approach 2 for the too much milk problem uses symmetric thread logic with notes. It can fail under heavy interleaving, causing a liveness violation where no milk is bought.
Identify critical sections and enforce mutual exclusion by blocking competing threads, ensuring only one thread executes in the critical section, with entry, exit, and remainder sections managing access.
Manage access to a shared global variable with critical sections, allowing multiple readers but one writer, and prevent deadlock, starvation, and timing or scheduling assumptions across uni- and multi-processor systems.
This lecture presents an asymmetric too much milk solution with threads A and B, where each uses the other’s node and milk state, highlighting complexity and need for synchronization primitives.
Learn how locks enforce mutual exclusion by a two-state lock—unlocked and locked—and how acquire and release ensure only one thread guards the critical section in entry, critical, and exit sections.
Learn how to use pthread mutexes to guard a shared queue by initializing with default attributes, and by acquiring and releasing locks around critical sections.
Use the same lock for all critical sections that modify the same shared variable, and different locks for different variables; acquire all locks when a section touches multiple variables.
Examine lock granularity from a global lock to object and field level locks, enabling parallel updates to V1 and V2, with higher concurrency but greater deadlock risk.
Demonstrate how two threads can deadlock by acquiring two locks in opposite orders, then show how enforcing a consistent lock order prevents deadlock in the critical section.
Avoid deadlocks and starvation with lock-based synchronization without assuming CPU speed or cores; random or FCFS scheduling prevents starvation, while priority schemes can cause it.
Explore semaphores as an integer variable accessed only via atomic weight and signal operations, guarding critical sections, blocking and waking threads, and distinguishing counting (accounting) and binary semaphores for resources.
Learn how to use semaphores as mutex-like locks by initializing to one, performing wait and post operations, and understanding sleep and wake behavior in critical sections for C++.
Explore bounded concurrent access with semaphores to limit how many threads enter a critical section, and learn signaling to enforce execution order using a boolean and busy waiting.
Learn how busy waiting wastes CPU cycles and can cause priority-based deadlock, and how semaphores provide a cleaner signaling method that blocks waiting threads.
Explore how multithreaded programs yield different outputs due to operating system thread scheduling, and learn to detect risk conditions, deadlocks, and starvation with tests or Hal Grind for posix threading.
Learn how multithreading exploits true parallelism on multi-core systems, and why proper workload distribution and avoiding blocking or dependencies are essential for scalable gains.
Manage shared memory and synchronize threads to prevent race conditions in multicore programming. Balance load across cores, handle uneven performance and sequential tasks, and plan for rigorous testing and debugging.
Explore how multithreading boosts responsiveness and cpu utilization on single-core and multi-core systems by keeping cores busy with ready threads during io waits and cache misses.
Design multithreaded programs by dividing tasks into independent threads and implementing each task as a separate thread, illustrated by a word processor, browser, and surveillance pipeline.
Divide a huge array of numbers into subtasks and run them on parallel threads, then combine the subtotals to obtain the final total.
Replace per-request thread creation with a thread pool of fixed worker threads that fetch tasks from a task queue, reducing latency and preventing resource exhaustion.
Explore massively parallel supercomputing, where thousands of general‑purpose cpus communicate via message passing to share data and synchronize, while minimizing inter‑cpu communication and maximizing bandwidth for nearby task placement.
Explore the readers-writers problem, a classic synchronization challenge, and learn to allow multiple readers while granting a single writer access to a shared dataset to prevent data races.
Learn how the readers-writers problem handles a shared dataset with two semaphores, read count tracking, and mutexes to coordinate readers and writers in the critical section.
Review implementation notes for a readers-writers solution, showing how readers block on the read write mutex while a writer updates the shared data. Discuss signaling and scheduler choices.
Shows how the writer process uses a read-write mutex to wait and enter the critical section, ensuring mutual exclusion for the shared data, then releases the lock for others.
Examine how a reader process uses a read count, mutex and read write mutex to safely enter and exit the critical section, ensuring mutual exclusion with writers.
Explore variations of the reader-writer problem, learn how read and write modes work in locks, and assess when the kernel provides locks and when overhead warrants avoidance.
Explain how readers have priority in the readers-writers problem, and how writer priority can be achieved by blocking new readers until no writers wait.
Explore the dining philosophers problem, a five philosophers concurrency problem that requires mutual exclusion, no deadlock, and no starvation while philosophers think, pick up chopsticks, and eat.
Explore a simple dining philosophers solution using five semaphores to enforce mutual exclusion, guard chopsticks, and use wait and signal to acquire both left and right chopsticks before eating.
Explain how semaphores guard chopsticks to ensure mutual exclusion, but the all-left grab pattern among five philosophers can cause deadlock, and the solution does not prevent it.
Examine deadlock handling in the dining philosophers problem using semaphores and locks, and compare fixes like limiting philosophers, requiring both chopsticks, or asymmetric ordering.
Explore deadlocks by examining the four necessary conditions: mutual exclusion, hold and wait, no preemption, and circular wait, and learn how preventing any one can stop deadlocks.
Investigate the mutual exclusion condition in deadlocks and why some resources, like printers, must be exclusively used, while read-only files can be shared.
Examine the hold and wait and no preemption deadlock conditions and how requiring resources upfront prevents them, though it lowers utilization and can cause starvation, with CPU registers and memory.
Explain the circular wait condition in deadlocks and how a total ordering of resources, with resources assigned increasing enumerations and requested in ascending order, prevents deadlocks.
Analyze the resource allocation graph to detect cycles and the circular wait condition, using request and assignment edges and single versus multiple resource instances.
Explore the resource allocation graph to identify cycles and determine the presence or absence of deadlock. Trace the finishing order where processes release resources to allow others to complete.
Analyze resource allocation graphs to identify cycles and deadlocks among processes. Examine single-instance versus multi-instance resources to see that cycles may guarantee deadlock or not, depending on resource counts.
Explore three approaches to deadlocks in operating systems: prevent by removing a condition, detect and recover by aborting or preempting resources, or ignore the problem since systems rely on developers.
Examine how user and kernel threads map to kernel threads via a many-to-one relationship, and evaluate the efficiency gains, blocking risks, and limits on parallelism.
Explain kernel threads and their 1-to-1 mapping with user threads, their scheduling by the OS, and how parallelism, concurrency, blocking I/O and overhead impact performance.
Explore many-to-many threading, where many user threads map onto a fixed pool of kernel threads, and the two-level model binds select threads 1-to-1. Most systems favor 1-to-1 mappings for performance.
Linux uses the term task to represent both processes and threads. It shows how clone and fork create tasks with varying sharing of resources based on flags.
Ace multithreading, Pthreads, synchronization, locks, semaphores, concurrency, deadlocks questions in competitive exams, job interviews, and OS course exams.
Do you know: A single-threaded process can only execute on one core even if the machine has eight cores? A multithreaded process can exploit the true hardware parallelism! What are data races? What is process synchronization? What are atomic operations? How to implement correct multithreaded programs without data races? What are locks and semaphores? How do we use locks and semaphores to implement correct synchronization solutions? What are deadlocks? What are the necessary conditions for deadlocks? How do operating systems deal with deadlocks? How do operating systems implement threads? How do operating systems implement locks to ensure correct mutual exclusion and synchronization? Learn the explanations to these and many more intriguing questions in this course!
Specifically, the course will cover the following in detail.
Why use threads in programs?
What are the overheads of using processes?
What is the key idea behind threads?
Difference between single vs multithreaded processes.
Benefits of using threads.
Pthread basics.
How to create a thread using Pthread?
How to pass parameters to a thread?
How to use Pthread_self, Pthread_equal?
How to terminate a thread?
How to use Pthread_join to wait for a thread to terminate?
How to return values from thread functions?
How to wait for threads?
How to detach a thread using Pthread_detach?
What are global variables in threads?
What is concurrency in programs?
What are race conditions and atomic operations?
What is synchronization?
What are the correctness properties for synchronization solutions?
How to enforce mutual exclusion?
What are locks?
How to use locks in Pthreads?
How to avoid deadlock with locks?
What are semaphores?
What are synchronization patterns--bounded concurrent access, signaling?
How to employ semaphores to avoid busy waiting?
How multithreading interacts with multicores?
What are the challenges of multicore programming?
How to designing multithreaded programs?
What are thread pools?
What is the readers-writers problem?
How to solve the readers-writers problem?
What is the dining philosophers problem?
How to solve the dining philosophers problem?
What are the 4 necessary conditions for deadlocks?
How to prevent deadlocks?
What is resource allocation graph?
How to handle deadlocks?
How to implement threads?
What are user threads and kernel threads?
How are threads implemented in Linux?
How are locks implemented?
What is the TestAndSet atomic instruction?
What are spin locks?
How do locks influence performance?
30 day money back guaranteed by Udemy.
Wisdom scholarships. If you are interested in taking one of our courses but cannot purchase it, you can apply for a scholarship to enroll. Learn more about the application process at my website.