Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Table of contents
1.
Introduction
2.
Mutex
2.1.
Working of a Mutex
2.2.
Example
3.
Frequently Asked Questions
3.1.
What is mutex lock and unlock?
3.2.
Why do we use mutex locks?
3.3.
Why mutex is faster than semaphore?
3.4.
What is the value of Pthread_mutex_initializer?
3.5.
Can we use mutex between processes?
4.
Conclusion
Last Updated: Mar 27, 2024
Medium

Mutex Lock

Author Sanjana Yadav
0 upvote
Leveraging ChatGPT - GenAI as a Microsoft Data Expert
Speaker
Prerita Agarwal
Data Specialist @
23 Jul, 2024 @ 01:30 PM
Operating Systems

Introduction

Thread synchronization is defined as a mechanism that assures that two or more concurrent processes or threads do not execute the same software segment known as a critical section at the same time. 

Synchronization strategies are used to control the access of processes to critical sections. 

When one thread begins executing the critical section (a serialized part of the program), the second thread must wait until the first thread has been completed. 

If correct synchronization procedures are not used, it may result in a race issue in which variable values are unpredictable and fluctuate based on the timings of process or thread context switches.

Mutexes are the most widely used method for achieving thread synchronization.

Also see, Introduction to Process Synchronization, Multiprogramming vs Multitasking

Read about - Lock based protocol in DBMS

Mutex

  • Mutex is a lock that is set before utilizing a shared resource and is released after using it. 
  • No other thread may access the locked code after the lock is set.
  • As a result, if thread t2 is scheduled while thread t1 is still using the shared resource and the code is locked by thread t1 using mutexes, thread t2 will be unable to access that piece of code.
  • As a result, synchronized access to shared resources in the code is ensured.

Working of a Mutex

  1. Assume one thread has used mutex to lock a region of code and is executing it.
  2. If the scheduler decides to do a context switch, all other threads that are ready to execute the same region will be unblocked.
  3. Only one thread will make it to execution, but if it tries to execute the same piece of code that is already locked,  it will go to sleep again.
  4. The context switch will happen repeatedly, but no thread will be able to execute the locked code until the mutex lock over it is released.
  5. Only the thread that locked the mutex will be able to unlock it.
  6. As a result, once a thread has locked a section of code, no other thread may execute that area until the thread that locked it has unlocked it.

As a result, while working on shared resources, this approach maintains thread synchronization.

The following two functions are used to create a lock once a mutex has been initialized:

  1. int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr): Creates a mutex, referenced by the mutex, with the attributes specified by attr. The default mutex property (NONRECURSIVE) is utilized if attr is NULL.
  • If successful, it returns 0 and the mutex state becomes initialized and unblocked.
  • If unsuccessful,it returns -1.

2. int pthread_mutex_lock(pthread_mutex_t *mutex) : Locks a mutex object, that identifies a mutex. If another thread has previously locked the mutex, the thread waits for it to become accessible. When a thread locks a mutex, it becomes the current owner and remains so until the same thread unlocks it. The lock may be used differently when a mutex contains the recursive attribute. When the same thread locks this type of mutex several times, the count is increased, and no waiting thread is posted. To decrease the count to zero, the owning thread must use pthread_mutex_unlock()  the same number of times.

  • If successful,returns 0.
  • If unsuccessful,returns -1.

The mutex can be unlocked and destroyed by using the two functions listed below.

  1. int pthread_mutex_unlock(pthread_mutex_t *mutex) :Releases a mutex object. If one or more threads are waiting to lock the mutex,   pthread_mutex_unlock()  causes one of them to return from   pthread_mutex_unlock()   with the mutex object. The mutex unlocks with no current owner if no threads are waiting for it. When a mutex contains the recursive property, the lock may be used differently. When the same thread locks this type of mutex numerous times, unlock will decrement the count, and no waiting thread will be allowed to continue executing with the lock. If the count reaches zero, the mutex is released, and any thread is waiting for it is posted.
  • If successful returns 0.
  • If unsuccessful,returns -1.

2. int pthread_mutex_destroy(pthread_mutex_t *mutex) :  Removes a mutex object, which is used to identify a mutex. Mutexes are used to secure shared resources. The mutex has been assigned to an incorrect value, but it may be re-initialized with the  pthread_mutex_unlock()  function.

  • If successful returns 0.
  • If unsuccessful,returns -1.

Example

This example shows how mutexes are used for thread synchronization

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
pthread_t thread_id[2];
int ctr;
pthread_mutex_t lock;
void *try_exmp(void *arg)
{
    pthread_mutex_lock(&lock);
    unsigned long i = 0;
    ctr += 1;
    printf("\n Task %d started\n", ctr);
    for (i = 0; i < (0xFFFFFFFF); i++)
        ;
    printf("\n Task %d finished\n", ctr);
    pthread_mutex_unlock(&lock);
    return NULL;
}
int main(void)
{
    int i = 0;
    int error;

    if (pthread_mutex_init(&lock, NULL) != 0)
    {
        printf("\n mutex init has failed\n");
        return 1;
    }
    while (i < 2)
    {
        error = pthread_create(&(thread_id[i]),NULL,
                                       try_exmp,NULL);
        if (error != 0)
            printf("\nThread can't be created :[%s]",
                   strerror(error));
        i++;
    }
    pthread_join(thread_id[0], NULL);
    pthread_join(thread_id[1], NULL);
    pthread_mutex_destroy(&lock);
    return 0;
}

In the code above:

  • At the start of the main function, a mutex is created.
  • When utilizing the shared resource 'ctr,' the same mutex is locked in the 'try_exmp()' function.
  • The identical mutex is unlocked at the end of the 'try_exmp()' function.
  • The mutex is deleted at the end of the main function after both threads have completed their tasks.

Output

Output

As a result, both start and finish logs of both the tasks are present this time.

As a result, Mutex was used to synchronize the threads.

Also Read About, FCFS Scheduling Algorithm

Get the tech career you deserve, faster!
Connect with our expert counsellors to understand how to hack your way to success
User rating 4.7/5
1:1 doubt support
95% placement record
Akash Pal
Senior Software Engineer
326% Hike After Job Bootcamp
Himanshu Gusain
Programmer Analyst
32 LPA After Job Bootcamp
After Job
Bootcamp

Frequently Asked Questions

What is mutex lock and unlock?

A mutex object that identifies a mutex is locked. Mutexes are used to secure shared resources. When a thread locks a mutex, it becomes the current owner and remains so until another thread unlocks it. When a mutex contains the recursive property, the lock may be used in a new way.

Why do we use mutex locks?

A Mutex, or Mutual Exclusion Object, is a type of object that allows only one process to access a resource at a time. The mutex object allows all processes to share the same resource, but only one process can utilize the resource at a moment. To solve the critical section problem, Mutex employs a lock-based approach. 

Why mutex is faster than semaphore?

A Mutex, or Mutual Exclusion Object, is a type of object that allows only one process to access a resource at a time. The mutex object allows all processes to share the same resource, but only one process can utilize the resource at a moment. To solve the critical section problem, Mutex employs a lock-based approach.

What is the value of Pthread_mutex_initializer?

If successful, the pthread_mutex_init() and pthread_mutex_destroy() functions return zero. Otherwise, an error number is returned to indicate the error.

Can we use mutex between processes?

Mutexes can be used to synchronize threads inside a process or between processes. If the mutexes are allocated in writable memory and shared across the collaborating processes and have been initialized for this job, they can be used to synchronize threads between processes.

Conclusion

  • Cheers if you reached here! In this blog, we learned about Mutex Lock in process synchronization.
  • We have covered the basic idea of Mutex.
  • We have also seen how it works.
  • Further, we saw an example to see the working of Mutex Lock.


On the other hand, learning never ceases, and there is always more to learn. So, keep learning and keep growing, ninjas!

Recommended Readings:

With this fantastic course from CodingNinjas, you can make learning enjoyable and stress-free.

Do check out The Interview guide for Product Based Companies as well as some of the Popular Interview Problems from Top companies like Amazon, Adobe, Google, Uber, Microsoft, etc. on Coding Ninjas Studio.

Also check out some of the Guided Paths on topics such as Data Structure and Algorithms, Competitive Programming, Operating Systems, Computer Networks, DBMS, System Design, etc. as well as some Contests, Test Series, Interview Bundles, and some Interview Experiences curated by top Industry Experts only on Coding Ninjas Studio.

Good luck with your preparation!

Live masterclass