What is Threading Mutex in Python – Simple Way

What is Threading Mutex in Python

In Python, a thread refers to a separate control flow within a single program that can run concurrently with another thread. It is a fundamental part of multithreading, which means concurrency and parallelism in Python. So, in this article, we are going to discuss what is threading mutex in Python. We are also gonna discuss mutex lock.

A mutex lock is implemented in Python using threading.Lock() class from the threading module. You have to import the threading module. A mutex lock is a primitive synchronization tool that is used to manage access to shared resources in a multithreaded program. A mutex lock’s main purpose or benefit is to prevent multiple threads from accessing shared resources simultaneously, avoiding potential conflicts and ensuring data consistency.

For implementing a mutex in Python, you need to use the Lock class from the Python threading module. The Lock class provides a way to create a mutex lock, and threads can acquire and release this lock to control access to critical sections of code.

Let’s import the important modules for implementing mutex in Python, which is done by importing Lock and Thread from the threading module.

from threading import Thread
from threading import Lock
Python

Threading can create a lock instance using Lock, acquire it before entering a critical section, and release it once the section has been accessed.

mutex_lock = Lock() # Create the Lock
mutex_lock.acquire() # Acquire the Lock
mutex_lock.release() # Release the Lock
Python

There is one more way to acquire the lock using the timeout, which adds waiting for some seconds within the set time frame, the function will return the value of False.

mutex_lock.acquire(timeout=10) #Acquire the Lock with a Timeout
Python

If you want to utilize the lock, you can do it through the context manager protocol using the with statement. This enables the section to be encapsulated within the block of the lock, ensuring the automatic release of the lock once the block is executed.

mutex_lock = Lock() # Create the lock
with mutex_lock: #acquire the lock
  # ....
Python

Using this context manager protocol is the most recommended approach as it delineates the start and end of the protected code. Moreover, it guarantees that the lock is released consistently, even in the presence of error within the section. We can also check whether the lock is currently held by a thread using the locked() function. See below example:

if mutex_lock.locked():
  #....
Python

Example to Understand What is Threading Mutex in Python

Let’s take an example to understand what is threading mutex in Python and how you can implement it through the python

import threading
import time

shared_counter = 0

mutex = threading.Lock()

def counter_increment():
    global shared_counter
    mutex.acquire()
    try:
        shared_counter += 1
        print(f"Thread {threading.current_thread()} increment counter to {shared_counter}")
    
    finally:
        mutex.release() # Release the mutex to allow other threads to acquire it
        
threads = []
for i in range(3):
    thread = threading.Thread(target=counter_increment, name=f"Thread-{i}")
    thread.append(thread)
    
# Start the threads
for thread in threads:
    thread.start()
    
# Wait for alll threads to finish
for thread in threads:
    thread.join()
    
print("Final Value of Shared Counter: ", shared_counter)       
  
Python

Output:

Thread Thread-0 incremented counter to 1
Thread Thread-1 incremented counter to 2
Thread Thread-2 incremented counter to 3
Final Value of Shared Counter: 3
What is Threading Mutex in Python

You can also define the mutex lock in the odoo using the __init__ function

def __init__(self):
   self._lock = threading.Lock()
   
@http.route('/Customer_create', type='json', auth='public', method=['POST'], csrf=False)
def create_customer(self, *args, **kwargs):
   try:
       if request.httprequest.method == 'POST':
           self._lock.acquire()
           result = request.jsonrequest.get('Email')
           try:
               tr = request.env['res.partner'].sudo().search([('email', '=', result)])
               if tr:
                   _logger.error(f"{tr.id} customer existing")
                   return {"Status": "Error", "Message": "Customer Already Exists"}
           except Exception as e:
               _logger.info(str(e))
           finally:
               self._lock.release()
Python

Mutexed helps to prevent race conditions and maintain data integrity in a concurrent program. When multiple threads are involved, proper synchronization is very crucial to avoid conflict and unexpected behavior.

Read More:

>> Encoding and Decoding Using Base64 Strings in Python
>> How to Setup SFTP Server on Ubuntu – 9 Steps

FAQ for What is Threading Mutex in Python

Here are some of the common questions about the threading.Lock() mutex in Python.

Do We Need To Protect Critical Sections In Light of the GIL?

Yes.
Only one thread can run at a time within a Python process thanks to the global interpreter lock (GIL) implemented by the most recent version of the Python interpreter.

Although a thread may change a variable, the operating system may switch context across threads during this time. This implies that a corrupted data version may be accessed by another thread trying to access or update the same variable (race situation).

Despite the GIL, Python still needs to safeguard critical areas.

Why Not Use a Boolean Variable?

Because of the Python interpreter’s global interpreter lock, only one thread can run at a time, and reading and writing boolean variables is an atomic operation. Thus, a single boolean variable might have the same result.

As of the time of writing, I think this is accurate, but only when using the most recent Python interpreter.

Later Python versions may alter this behavior, and third-party Python interpreters that don’t use a global interpreter lock may behave differently.

What If We Don’t Release The Lock?

It will called a concurrency bug.

If the lock is not released, it can not be acquired again and the code protected by the critical section can’t be executed again.

What If We Ignore the Lock?

Ignoring the lock is a concurrency bug.

Code can be written to make some threads obey the lock while others do not. This will probably cause a race condition and negate the initial goal of having a lock.

Is the threading.Lock Reentrant?

No.

A reentrant lock can be re-acquired by the same thread if it is held by it.

The threading.Thread locks are not reentrant, a deadlock bug (a concurrency failure condition) will occur if a thread obtains the lock and tries to acquire it again in a different section of the code.

Reentrant mutual exclusion locks are available in the threading.RLock class.

So this is all about what is threading mutex in Python, If you have any doubt regarding this topic feel free to comment. 🙂

Happy Coding!

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.