ScholarQuill logoScholarQuillUniversity Notes
My Semester
Explore Notes
Past Papers12 New
Video CoursesNew
Search
Settings
Study Tools
GPA/CGPA Calculator
Schedule & To-Do
Student Portal
Contact
Contact
ScholarQuill logo
My Semester
Explore Notes
Past Papers12 New
Video CoursesNew
Search
Settings
GPA/CGPA Calculator
Schedule & To-Do
Student Portal
Contact
ScholarQuill logoScholarQuillUniversity Notes
Study PortalCOMP3139Locks Semaphores
Ctrl + K
Login
Explore
Search
Semester
Papers
CGPA
    COMP3139

    Parallel & Distributed Computing

    Progress0 / 33 done
    Topics33
    1Introduction to Parallel and Distributed Systems2Why Use Parallel and Distributed Systems?3Speedup and Amdahl's Law
    4Multi Processors (Shared Memory)5Networks of Workstations (Distributed Memory)6Clusters (Latest Variation)
    7Threads and Shared Memory8Processes and Message Passing9Distributed Shared Memory (DSM)10Distributed Shared Data (DSD)11Parallel Algorithms12Concurrency and Synchronization13Data and Work Partitioning14Common Parallelization Strategies15Granularity16Load Balancing
    17Parallel Search18Parallel Sorting19Shared-Memory Programming20Threads in Shared-Memory Programming21P Threads22Locks and Semaphores23Distributed-Memory Programming24Message Passing25Map Reduce26Distributed-Memory Programming with PI27Google's Map Reduce28Hadoop29Other Parallel Programming Systems30Tread Marks31Distributed Shared Memory
    32Scoped Behavior and Abstract Data Types
    33Process Templates
    7 min read
    Topic 22 of 33
    Topic Study Note Illustration
    22

    Locks and Semaphores

    Locks and semaphores are two of the most commonly used synchronization primitives in parallel and concurrent programming. Both are used to manage access to shared resources, preventing...

    Locks and Semaphores

    Locks and semaphores are two of the most commonly used synchronization primitives in parallel and concurrent programming. Both are used to manage access to shared resources, preventing race conditions, ensuring mutual exclusion, and allowing synchronization between threads or processes. While they are conceptually similar, they are used in slightly different ways and offer different levels of control.

    Let’s break down locks and semaphores, understand their differences, and explore their usage in programming.


    1. Locks (Mutexes)

    A lock is a synchronization mechanism used to enforce mutual exclusion (mutex) by ensuring that only one thread or process can access a critical section of code at a time. When a thread locks a resource, no other thread can access it until the lock is released.

    Key Points about Locks:

    • Mutual Exclusion: Locks provide mutual exclusion, meaning only one thread can execute a critical section at any given time.
    • Blocking: If a thread tries to acquire a lock that is already held by another thread, it will block (wait) until the lock is released.
    • Unlocking: Once a thread finishes executing the critical section, it releases the lock, allowing other threads to acquire it.

    Common Operations for Locks:

    • lock: A thread locks a mutex or a lock, blocking if it’s already locked.
    • unlock: A thread releases a lock, allowing other threads to acquire it.

    Types of Locks:

    • Mutex (Mutual Exclusion Lock): A type of lock that can only be acquired by one thread at a time.
    • Reentrant Mutex: A type of mutex that allows the same thread to lock the mutex multiple times without causing deadlock.
    • Spinlock: A lock where a thread repeatedly checks (spins) to see if the lock is available. It is typically used when the lock is expected to be held for a very short period of time.

    Example (C using PThreads):

    #include <pthread.h>
    #include <stdio.h>
    
    pthread_mutex_t lock;  // Declare a mutex
    
    void* thread_func(void* arg) {
        pthread_mutex_lock(&lock);  // Acquire the lock
        printf("Thread is executing critical section\n");
        pthread_mutex_unlock(&lock);  // Release the lock
        return NULL;
    }
    
    int main() {
        pthread_t thread1, thread2;
        pthread_mutex_init(&lock, NULL);  // Initialize the mutex
    
        // Create two threads
        pthread_create(&thread1, NULL, thread_func, NULL);
        pthread_create(&thread2, NULL, thread_func, NULL);
    
        // Wait for both threads to finish
        pthread_join(thread1, NULL);
        pthread_join(thread2, NULL);
    
        pthread_mutex_destroy(&lock);  // Clean up the mutex
        return 0;
    }
    

    In this example, the mutex ensures that only one thread at a time can enter the critical section where the shared resource is being accessed.


    2. Semaphores

    A semaphore is another synchronization primitive, but it is more general than a lock. It is essentially a counter that controls access to resources. Semaphores can be used for both mutual exclusion and synchronization between threads or processes.

    A semaphore is initialized with an integer value, and operations on a semaphore involve incrementing or decrementing that value. Semaphores are typically used to signal one or more threads that they can proceed with a certain task or to limit the number of threads that can access a specific resource.

    Types of Semaphores:

    • Binary Semaphore (Mutex): A special case of a semaphore where the counter can only take two values: 0 or 1. It is used to implement mutual exclusion (like a lock).
    • Counting Semaphore: A semaphore where the counter can take any non-negative integer value. It is used to limit access to a pool of resources (e.g., database connections, threads).

    Operations on Semaphores:

    • wait (P operation): Decreases the semaphore’s counter. If the counter is already zero, the calling thread will block until the counter becomes positive.
    • signal (V operation): Increases the semaphore’s counter. If there are threads waiting, one of them may be unblocked.

    The names P and V come from the Dutch words "proberen" (to test) and "verhogen" (to increment), and are used in some academic contexts.

    Example (C using PThreads with a Counting Semaphore):

    #include <pthread.h>
    #include <stdio.h>
    #include <semaphore.h>
    
    sem_t semaphore;  // Declare a semaphore
    
    void* thread_func(void* arg) {
        sem_wait(&semaphore);  // Decrement semaphore and block if it's 0
        printf("Thread is executing critical section\n");
        sem_post(&semaphore);  // Increment semaphore (release)
        return NULL;
    }
    
    int main() {
        pthread_t thread1, thread2;
    
        sem_init(&semaphore, 0, 1);  // Initialize semaphore (binary, value 1)
    
        // Create two threads
        pthread_create(&thread1, NULL, thread_func, NULL);
        pthread_create(&thread2, NULL, thread_func, NULL);
    
        // Wait for both threads to finish
        pthread_join(thread1, NULL);
        pthread_join(thread2, NULL);
    
        sem_destroy(&semaphore);  // Clean up the semaphore
        return 0;
    }
    

    In this example, the semaphore is used to control access to the critical section. If one thread holds the semaphore (decrements the count), the other thread will block until the first thread releases the semaphore by incrementing the count.


    3. Differences Between Locks and Semaphores

    While both locks and semaphores are used to manage synchronization, they differ in functionality and use cases.

    Feature Locks (Mutexes) Semaphores
    Purpose Provide mutual exclusion for critical sections of code Control access to shared resources and synchronize threads
    Type of Resource Binary (locked/unlocked) Can be binary (mutex) or counting (multiple resources)
    Value Can only be locked (1) or unlocked (0) Can hold any integer value (typically ≥ 0)
    Operations lock(), unlock() wait(), signal()
    Blocking A thread blocks until the lock is released A thread blocks if the semaphore count is 0 (for counting semaphores)
    Typical Use Protecting a single resource or critical section Managing access to a pool of resources (e.g., limiting the number of threads accessing a resource)
    Counting Ability No counting mechanism (binary state) Can count (e.g., counting semaphores)

    When to Use Locks:

    • When you need exclusive access to a single shared resource.
    • When only one thread should be allowed to enter a critical section at any given time (e.g., updating a shared variable).

    When to Use Semaphores:

    • When you need to manage access to a pool of resources or control the concurrency level (e.g., limiting the number of threads that can access a database).
    • When you need to synchronize threads, ensuring they wait for a certain condition before proceeding.

    4. Advantages and Disadvantages

    Locks:

    • Advantages:
      • Simpler to use for protecting individual critical sections.
      • Prevents multiple threads from entering a critical section simultaneously.
    • Disadvantages:
      • If not used properly, can lead to deadlock (if threads acquire multiple locks in different orders).
      • No direct support for managing multiple shared resources or concurrency levels.

    Semaphores:

    • Advantages:
      • Can manage access to multiple resources or a pool of resources (e.g., limiting the number of threads accessing a resource).
      • More flexible than locks for certain types of synchronization.
    • Disadvantages:
      • Slightly more complex to use correctly compared to simple locks.
      • The counter value must be managed carefully to avoid inconsistencies.

    5. Conclusion

    Locks and semaphores are essential tools for synchronization in concurrent programming. While locks are best suited for mutual exclusion, where only one thread should access a resource at a time, semaphores provide more general mechanisms for managing resources and synchronizing threads in more complex scenarios. Understanding when and how to use these tools is critical for developing correct, efficient, and scalable parallel programs.

    ← Previous topic 21
    P Threads
    Next topic 23 →
    Distributed-Memory Programming

    Past Papers

    Open this section to view and download past papers

    Click on Show Past Papers to load available exam papers.

    Reading Progress
    0%
    7mremaining
    1.2kwords
    Intermediatelevel
    On This Page

    No headings found

    Study Toolkit

    Subject Portal

    Parallel & Distributed Computing