Problems on Synchronization

  1. Two processes, A and B, both increment a shared counter variable counter initialized to 0. Process A performs 3 increments, while Process B performs 2 increments. They use a semaphore S initialized to 2 to control access to the counter, but they mistakenly perform a P operation after the increment instead of before. Assuming both processes can enter the critical section simultaneously due to the semaphore's initial value, what are the possible final values of counter? How many different final values are possible?

  2. Consider two processes, X and Y, manipulating two shared variables: var1 and var2, both initialized to 100. Process X executes a sequence of operations that doubles var1 and then adds 50 to var2. Process Y executes a sequence of operations that halves var2 and then subtracts 30 from var1. A single semaphore S initialized to 1 is supposed to control access to both variables, but due to a coding error, the semaphore is only used when accessing var1. Identify the maximum and minimum possible final values of var1 and var2.

  3. Two processes, P1 and P2, access a shared variable balance initialized to 0. P1 can increment balance by 10, up to 3 times. P2 can decrement balance by 5, up to 4 times. They attempt to use a semaphore S initialized to 1 for synchronization. However, P1 only uses the semaphore for its first operation, and P2 only uses it for its last operation. What are the possible final values of balance?

  4. Two processes, M and N, append integers to a shared list L initially containing [1, 2]. Process M appends the numbers 3 and 4 in sequence, while Process N appends the numbers 5 and 6 in sequence. They use a semaphore S initialized to 2 to synchronize access to the list. However, due to a logic error, M performs a P operation after appending 3 but forgets to perform it again after appending 4. N performs a P operation before appending 5 but does not perform any semaphore operations thereafter. Given this scenario, how many different final states can list L have, and what are they?

  5. A counting semaphore S is initialized to 4. Initially, 3 V operations are performed, followed by 2 P operations, another 4 V operations, and finally 5 P operations. What is the final value of S after these operations?

  6. A counting semaphore S is initialized to 7. The sequence of operations is as follows: P, V, P, V, P, V, P, and then two consecutive V operations. What is the final value of S after this sequence?

  7. Imagine a system with three threads, T1, T2, and T3, and two semaphores, S1 and S2, both initialized to 1. Thread T1 executes a P operation on S1, enters a critical section, and within it, executes a P operation on S2 before leaving the critical section and executing a V operation on S1. Concurrently, T2 executes a P operation on S2, enters another critical section, and performs a P operation on S1 before exiting and performing a V operation on S2. If T3 attempts to perform P operations on both S1 and S2 in the given order, describe the sequence of events that would allow all threads to complete without deadlock, specifying any conditions under which a deadlock might occur.

  8. In a complex system with five processes (A, B, C, D, E) competing for three identical resources, each process requires two resources to complete its task. Using semaphores, design a synchronization scheme that ensures deadlock-free access to the resources for all processes. Describe how your scheme allows each process to safely acquire and release resources, ensuring maximum resource utilization without leading to a deadlock or starvation.

  9. Describe a complex synchronization pattern involving multiple semaphores that could be used to enforce a specific order of execution among four processes (P1 through P4), such that P1 must complete before P2 and P3 can start, and P4 can only start after P2 and P3 have both completed. Detail the semaphore operations required to achieve this pattern, considering any potential risks of deadlock or unnecessary waiting.

The Office Visit Synchronization Challenge

In the local government service office, there's a unique system for managing visitors. The office is designed to handle a specific number of visitors at any given time due to space constraints. The setup is as follows:

  • There is 1 chair directly in front of the service officer, where the current visitor is being attended to.

  • Additionally, there is a waiting area with 4 chairs for visitors waiting for their turn.

  • If a visitor arrives and all chairs (both the chair in front of the officer and those in the waiting area) are occupied, they must leave and return at another time.

To manage this system efficiently and ensure fair access to service, the office decides to implement a process synchronization system using mutexes and semaphores.

Visitors are represented as processes that must follow a specific protocol when they arrive:

  1. Check if there is an available seat in the waiting area.

  2. If a seat is available, the visitor/process waits in the waiting area until it's their turn.

  3. When it's their turn, the visitor moves from the waiting area to the chair in front of the officer.

  4. After the visitor's work is done with the officer, they leave, and the next visitor is allowed in.

To facilitate this, two synchronization mechanisms are proposed:

  • A mutex (mutex_office) is used to protect the critical section where the check and update of the number of available seats are performed. This ensures that no two visitors are trying to take the same seat.

  • A semaphore (sem_waitingArea) initialized to 4, representing the number of seats in the waiting area. This semaphore is used to manage how many visitors can wait in the waiting area. There's no need for a semaphore for the single chair in front of the officer since it's implied that only one visitor can be serviced at a time, and moving from the waiting area to this chair is part of the critical section managed by the mutex.

The Challenge:

Design a synchronization mechanism that:

  • Ensures no visitor sits in a chair that's already taken.

  • Maximizes the office's capacity without exceeding the limit.

  • Ensures fairness, so visitors are served in the order they arrive as long as they can find a seat in the waiting area.

  • Allows for a visitor to leave if they arrive and find no available seating.

Questions:

  1. How would you implement the synchronization system to meet the above requirements using the mutex_office and sem_waitingArea?

  2. Describe the sequence of operations (P and V operations for the semaphore, lock and unlock operations for the mutex) a visitor process must perform from arrival to departure.

  3. In a scenario where the waiting area is full, and one visitor in front of the officer leaves, explain the mechanism that decides which of the waiting visitors next occupies the chair in front of the officer.

  4. How can the system ensure that visitors who have to leave due to lack of space are given priority when they return?

  5. Consider an extension of this problem where there is more than one service officer, each with their chair. How would you modify your synchronization strategy to accommodate multiple service officers while still ensuring fair and efficient service?

The Community Library System

Scenario:

In a small town, there's a community library that has become a central hub for knowledge seekers and literature enthusiasts. The library has a unique system for managing its collection of books, periodicals, and digital resources. To keep up with the times and the demands of its patrons, the library has digitized its catalog, allowing members to browse, reserve, and review resources online. This system is crucial for maintaining an efficient operation, especially given the library's limited physical space and budget constraints.

The Challenge:

The library's digital catalog system faces two primary types of users:

  1. Browsers - These users simply browse the catalog to check the availability of books, read descriptions, and look at reviews. They make up the majority of the system's traffic and do not modify the catalog content.

  2. Contributors - A smaller group of users, including librarians and some members of the community, have the rights to update the catalog. This includes adding new titles, updating book descriptions, posting announcements, and editing reviews.

To ensure the integrity of the catalog and provide a pleasant user experience, the library's system must meet several critical requirements:

  • Allow multiple Browsers to access the catalog simultaneously without interference.

  • Ensure that when a Contributor is updating the catalog, no Browser can access the part of the catalog being updated to prevent them from getting outdated or inconsistent information.

  • Allow a Contributor to update the catalog only when there are no active Browsers in the section they wish to update, preventing potential conflicts and ensuring data integrity.

  • Ensure fairness so that Contributors can make necessary updates timely without being indefinitely blocked by a continuous stream of Browsers.

Questions:

  1. Design a synchronization mechanism for the library's digital catalog system that accommodates both Browsers and Contributors efficiently. What kind of locks, semaphores, or other synchronization tools would you use to meet the above requirements?

  2. How would you handle a situation where a Contributor needs to make an urgent update while multiple Browsers are accessing the catalog? Describe the steps to ensure the update is made without violating the system's integrity.

  3. Suppose the system is heavily loaded with Browsers most of the time. How would you ensure that Contributors aren’t starved of the opportunity to make updates?

  4. Consider a scenario where a new release of books is to be added to the catalog, requiring significant updates across various sections. How would your synchronization strategy handle large-scale updates that affect multiple parts of the catalog?

  5. If the library wants to introduce a feature that allows Contributors to make minor updates (like correcting a typo) that don't necessitate blocking Browsers, how would you modify your synchronization mechanism to support this?

Below is a piece of pseudo-code that illustrates a scenario involving mutexes and semaphores where race conditions can still occur. The code simulates a simplified scenario where several workers (threads) update shared resources in a system that's supposed to use synchronization mechanisms to prevent race conditions. However, due to certain oversights, race conditions are still possible. Suggest fixes to it.

# Pseudo code illustrating a flawed synchronization mechanism

# Initialize synchronization primitives
mutex = Mutex() # A mutex for protecting critical sections
semaphore = Semaphore(2) # A semaphore to control access, initialized to allow 2 concurrent accesses

shared_resource_1 = 0 # A shared resource
shared_resource_2 = 0 # Another shared resource

def worker_thread_A():
    while True:
        semaphore.wait() # Intended to control access to the shared resources
        mutex.lock() # Protect the critical section

        # Critical section starts
        shared_resource_1 += 1
        shared_resource_2 += 2
        # Critical section ends

        mutex.unlock()
        semaphore.signal()

def worker_thread_B():
    while True:
        semaphore.wait() # Intended to control access to the shared resources

        # Critical section starts
        if shared_resource_1 > shared_resource_2:
            shared_resource_1 -= 1
        else:
            shared_resource_2 -= 1
        # Critical section ends

        semaphore.signal()

# Main program that starts multiple instances of worker_thread_A and worker_thread_B

Below is a piece of pseudo code that illustrates a scenario prone to deadlock due to incorrect ordering and handling of mutex locks. The code simulates a system where two processes (or threads) need to acquire locks on two resources to proceed with their tasks. However, due to the manner in which the locks are acquired and released, a deadlock situation can occur. Propose fixes.

# Pseudo code illustrating a scenario prone to deadlock

# Initialize mutexes for two shared resources
mutex_resource_A = Mutex()
mutex_resource_B = Mutex()

def process_1():
    while True:
        mutex_resource_A.lock() 
        sleep(1)

        mutex_resource_B.lock() 
        sleep(1)

        mutex_resource_B.unlock()
        mutex_resource_A.unlock()

def process_2():
    while True:
        mutex_resource_B.lock() 
        sleep(1)

        mutex_resource_A.lock()
        sleep(1)

        mutex_resource_A.unlock()
        mutex_resource_B.unlock()

# Main program that starts process_1 and process_2