Create mutex in linux

Mutex lock for Linux Thread Synchronization

Thread synchronization is defined as a mechanism which ensures that two or more concurrent processes or threads do not simultaneously execute some particular program segment known as a critical section. Processes’ access to critical section is controlled by using synchronization techniques. When one thread starts executing the critical section (a serialized segment of the program) the other thread should wait until the first thread finishes. If proper synchronization techniques are not applied, it may cause a race condition where the values of variables may be unpredictable and vary depending on the timings of context switches of the processes or threads.

Thread Synchronization Problems
An example code to study synchronization problems :

How to compile above program?
To compile a multithreaded program using gcc, we need to link it with the pthreads library. Following is the command used to compile the program.

gfg@ubuntu:~/$ gcc filename.c -lpthread

In this example, two threads(jobs) are created and in the start function of these threads, a counter is maintained to get the logs about job number which is started and when it is completed.

Job 1 has started Job 2 has started Job 2 has finished Job 2 has finished

Problem: From the last two logs, one can see that the log ‘Job 2 has finished’ is repeated twice while no log for ‘Job 1 has finished’ is seen.

Why it has occurred ?
On observing closely and visualizing the execution of the code, we can see that :

  • The log ‘Job 2 has started’ is printed just after ‘Job 1 has Started’ so it can easily be concluded that while thread 1 was processing the scheduler scheduled the thread 2.
  • If we take the above assumption true then the value of the ‘counter’ variable got incremented again before job 1 got finished.
  • So, when Job 1 actually got finished, then the wrong value of counter produced the log ‘Job 2 has finished’ followed by the ‘Job 2 has finished’ for the actual job 2 or vice versa as it is dependent on scheduler.
  • So we see that its not the repetitive log but the wrong value of the ‘counter’ variable that is the problem.
  • The actual problem was the usage of the variable ‘counter’ by a second thread when the first thread was using or about to use it.
  • In other words, we can say that lack of synchronization between the threads while using the shared resource ‘counter’ caused the problems or in one word we can say that this problem happened due to ‘Synchronization problem’ between two threads.

How to solve it ?

The most popular way of achieving thread synchronization is by using Mutexes.

Mutex

  • A Mutex is a lock that we set before using a shared resource and release after using it.
  • When the lock is set, no other thread can access the locked region of code.
  • So we see that even if thread 2 is scheduled while thread 1 was not done accessing the shared resource and the code is locked by thread 1 using mutexes then thread 2 cannot even access that region of code.
  • So this ensures synchronized access of shared resources in the code.

Working of a mutex

  1. Suppose one thread has locked a region of code using mutex and is executing that piece of code.
  2. Now if scheduler decides to do a context switch, then all the other threads which are ready to execute the same region are unblocked.
  3. Only one of all the threads would make it to the execution but if this thread tries to execute the same region of code that is already locked then it will again go to sleep.
  4. Context switch will take place again and again but no thread would be able to execute the locked region of code until the mutex lock over it is released.
  5. Mutex lock will only be released by the thread who locked it.
  6. So this ensures that once a thread has locked a piece of code then no other thread can execute the same region until it is unlocked by the thread who locked it.

Hence, this system ensures synchronization among the threads while working on shared resources.

A mutex is initialized and then a lock is achieved by calling the following two functions : The first function initializes a mutex and through second function any critical region in the code can be locked.

    1. int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr) : Creates a mutex, referenced by mutex, with attributes specified by attr. If attr is NULL, the default mutex attribute (NONRECURSIVE) is used. Returned value
      If successful, pthread_mutex_init() returns 0, and the state of the mutex becomes initialized and unlocked.
      If unsuccessful, pthread_mutex_init() returns -1.
    2. int pthread_mutex_lock(pthread_mutex_t *mutex) : Locks a mutex object, which identifies a mutex. If the mutex is already locked by another thread, the thread waits for the mutex to become available. The thread that has locked a mutex becomes its current owner and remains the owner until the same thread has unlocked it. When the mutex has the attribute of recursive, the use of the lock may be different. When this kind of mutex is locked multiple times by the same thread, then a count is incremented and no waiting thread is posted. The owning thread must call pthread_mutex_unlock() the same number of times to decrement the count to zero. Returned value
      If successful, pthread_mutex_lock() returns 0.
      If unsuccessful, pthread_mutex_lock() returns -1.

The mutex can be unlocked and destroyed by calling following two functions :The first function releases the lock and the second function destroys the lock so that it cannot be used anywhere in future.

    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 those threads to return from pthread_mutex_lock() with the mutex object acquired. If no threads are waiting for the mutex, the mutex unlocks with no current owner. When the mutex has the attribute of recursive the use of the lock may be different. When this kind of mutex is locked multiple times by the same thread, then unlock will decrement the count and no waiting thread is posted to continue running with the lock. If the count is decremented to zero, then the mutex is released and if any thread is waiting for it is posted. Returned value
      If successful, pthread_mutex_unlock() returns 0.
      If unsuccessful, pthread_mutex_unlock() returns -1
    2. int pthread_mutex_destroy(pthread_mutex_t *mutex) : Deletes a mutex object, which identifies a mutex. Mutexes are used to protect shared resources. mutex is set to an invalid value, but can be reinitialized using pthread_mutex_init(). Returned value
      If successful, pthread_mutex_destroy() returns 0.
      If unsuccessful, pthread_mutex_destroy() returns -1.

An example to show how mutexes are used for thread synchronization

Источник

In C/C++ on linux, how do I create a prelocked mutex

What attribute do I use to create a pthreads mutex that is locked by the creating thread at creation time?

Such a mechanism doesn’t seem to exist. If you could elaborate on your need for such a requirement, people of SO could help you solve it.

4 Answers 4

It doesn’t appear to be supported by the pthreads mutex interfaces. You’re going to have to mutually lock it, and use some other synchronization method to keep other threads from grabbing it before you do (which is what I’m assuming you want to do here), in semi-pseudocode below:

pthread_mutex_lock(my_pthread_creation_mutex); pthread_mutex_init(new_mutex, mutex_attributes); pthread_mutex_lock(new_mutex); pthread_mutex_unlock(my_pthread_creation_mutex); 

The closest you can get with what you want is to use semaphores. They can be initialized with a specific value. On linux (as you have that tag) man sem_overview should give you a good introduction to that topic

This answer is correct, but it’s still subject to the same concerns I mentioned in my answer, namely that if OP needs such a thing, the code is probably wrong, because there’s no way correct code can need it. (On the other hand, with named semaphores this could work, since O_EXCL|O_CREAT can do the necessary synchronization for you.)

There is no observably-distinct difference between a mutex that is created in the locked state, and one that is created and subsequently locked by the thread that creates it. That is, if you write (hypothetical):

pthread_mutex_init(&mutex, 0); pthread_mutex_lock(&done); /* done */ 

In both cases, it’s UB for any other thread to attempt in any way to access the mutex before the creating thread reaches the «done» comment and subsequently performs some action that could let other threads know the mutex exists.

The fact that you think you need a pre-locked mutex suggests strongly to me that you’re trying to do something very very wrong, and probably invoking undefined behavior.

Sorry, SO wouldn’t let me post my comment. No idea why. @R Mostly asked as an academic question. I seem to remember seeing a reference to prelocked mutexes, but it might have been to preset semaphores. In either case, I use an stl vector to track activity in several threads. The master thread was dutifully checking that the «time» stored by each thread was incrementing. I thought I had a race condition where master thread was checking a thread node before it updates. Wasn’t the problem. Adding a mutex to the node was a thought for preventing the master looking too quickly. Thanks.

Источник

Читайте также:  Asus eee pc linux iso
Оцените статью
Adblock
detector