Mutual Exclusion in Synchronization


Introduction

To avoid information loss and discrepancies, it is essential to make certain that discussed assets are obtained in an organized way when using concurrent programming methods, in which numerous threads or methods operate simultaneously. Mutual exclusion, which ensures that just a single string or procedure has access to a crucial area or resource that everyone shares at any point in time, is how this is accomplished.

In this article, we will be talking about Mutual Exclusion in Synchronization, its various techniques, use cases, and example implementation through Python.

What is Mutual Exclusion in Synchronization?

A key component of synchronizing simultaneous tasks is mutual exclusion, which enables various threads to make use of resources that are shared with no tampering with one another's operation. Race conditions, in which various threads attempt to gain access to and change shared information simultaneously, can be prevented by implementing mutual exclusion.

Techniques of Mutual Exclusion in Synchronization

Mutual exclusion can be achieved using a variety of strategies, such as the following−

  • Locks/Mutexes − To safeguard resources that are shared, synchronization primitives called locks or mutexes (short for mutual exclusion) are implemented. There are two possible states for a lock: locked and unlocked. An operating system or procedure must obtain the lock before being able to utilize the resource that is shared. The requesting string is going to be restricted as long as the lock has been released if it has already been locked by a distinct thread.

  • Semaphores − Another synchronization tool utilized for mutual exclusion is the semaphore. They could be thought of as an all-purpose lock. When a thread needs to enter the critical area, semaphores keep track of a counter and decrease it. The running thread becomes immobilized if the counter decreases, signifying that the critical portion has become in use.

  • Atomic Operations − Without using locks or semaphores, certain processors offer atomic operations which may be employed to guarantee mutual exclusion. Atomic operations are advantageous for modifying shared parameters because they are unbreakable and can't be stopped. A property of a variable may only be altered using atomic compare-and-swap (CAS) procedures, for instance, if the value of the variable coincides with the value that is anticipated.

  • Software-based Techniques − Mutual exclusion can be achieved using a variety of software-based algorithms and strategies, including Peterson's algorithm, Dekker's algorithm, or Lamport's bakery algorithm. These techniques make a guarantee that only a single thread at one point is able to utilize the critical component by combining factors, flags, and busy-waiting.

Use cases of Mutual Exclusion in Synchronization

Below are a few instances of mutual exclusion in synchronization that happened in real-time −

  • Printer Spooling − Several procedures or individuals may ask for printed documents at once in an OS with a number of users. Mutual exclusion is used to guarantee that just one process at the moment has access to the printer. In order to provide restricted access to the printer, avoid conflicts, and guarantee that printed positions are dealt with in the proper order, a lock or semaphore is used.

  • Bank Account Transactions − Many people may simultaneously try to obtain and alter their financial accounts in an electronic banking system. In order to avoid problems like overloading or erratic accounts, mutual exclusion is required. A single transaction is allowed to access a certain bank account at a time using locks or other synchronization primitives, maintaining the confidentiality of the information and avoiding conflicts.

  • Traffic Signal Control − Traffic signals at a crosswalk must be coordinated in order to safely manage the movement of transport vehicles. In order to avoid competing communication from being displayed at once, mutual exclusion is used. One indicator is allowed to be present at a time thanks to the mutual exclusion rule, which promotes efficient and organized traffic flow.

  • Resource Allocation in Shared Database − Mutual exclusion is essential to preserving information consistency in database systems where various procedures or transactions access information that is shared concurrently. For instance, mutual exclusion mechanisms make absolutely certain that just a single transaction is able to alter identical data at a time, hindering disagreements and maintaining data integrity when two separate operations try to alter the same information concurrently.

  • Accessing Shared Memory in Real-Time Systems − Mutual exclusion is required in real-time systems in which operations or procedures require shared memory to facilitate interaction or cooperation. Important memory-sharing regions are protected using synchronization basic functions like locks or semaphores, which make sure that only a single assignment is able to use and alter the area of shared memory at once.

Example of Mutual Exclusion in Synchronization

Below is an example of Mutual Exclusion in Synchronization implementation in Python.

In this example, multiple threads are created to increment a shared variable (shared_variable) by 1. The critical section where the shared variable is modified is protected by a mutex lock (mutex). Each thread acquires the lock before entering the critical section and releases it after completing the critical section. The mutex lock ensures that only one thread can modify the shared variable at a time, preventing race conditions and ensuring the correctness of the final result.

import threading

# Shared variable
shared_variable = 0

# Mutex lock
mutex = threading.Lock()

# Function to increment the shared variable
def increment():
   global shared_variable
   for _ in range(100000):
      # Acquire the lock
      mutex.acquire()
        
      # Critical section
      shared_variable += 1
        
      # Release the lock
      mutex.release()

# Create multiple threads
threads = []
for _ in range(5):
   thread = threading.Thread(target=increment)
   threads.append(thread)

# Start the threads
for thread in threads:
   thread.start()

# Wait for all threads to complete
for thread in threads:
   thread.join()

# Print the final value of the shared variable
print("Shared Variable:", shared_variable)

Output

Shared Variable: 500000

Conclusion

It is crucial to carefully plan and analyze synchronization strategies, take into account alternative strategies when necessary, apply to lock at the proper level of granularity and carry out extensive testing and profiling to find and fix any potential synchronization problems if you want to use mutual exclusion effectively.

Programmers can use synchronization methods to achieve an equilibrium between preserving the confidentiality of data, enabling cooperation, and guaranteeing the general efficacy and dependability of simultaneous platforms through comprehending the benefits and drawbacks of mutual exclusion.

Updated on: 17-Jul-2023

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements