Story
According to the man page https://linux.die.net/man/3/pthread_mutex_lock
The mutex object referenced by mutex shall be locked by calling pthread_mutex_lock(). If the mutex is already locked, the calling thread shall block until the mutex becomes available.
I have a program with a thread. Here is the program flow:
- The main process and the thread always call
pthread_mutex_lockinside of a loop. - When the main process is holding the lock, the thread which is asking for lock, blocks (waiting for lock to be granted).
- When the main process releases the lock with
pthread_mutex_unlock, the thread should suddenly get the lock. - When the main process asks for the lock again, the main process should wait for the thread to release the lock.
The problem is that, at point 3, the thread does not suddenly get the lock as soon as the main process releases the lock. The main process gets it first when it calls to pthread_mutex_lock in the next loop cycle (at point 4).
How to deal with this situation?
Question
How can I make the thread get the lock as soon as the main process releases the lock?
Simple code to reproduce the problem
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER;
void *
my_thread(void *p)
{
(void)p;
while (1) {
pthread_mutex_lock(&my_mutex);
printf("The thread is holding the lock...\n");
sleep(1);
pthread_mutex_unlock(&my_mutex);
}
}
int
main()
{
pthread_t t;
pthread_create(&t, NULL, my_thread, NULL);
pthread_detach(t);
while (1) {
pthread_mutex_lock(&my_mutex);
printf("The main process is holding the lock...\n");
sleep(1);
pthread_mutex_unlock(&my_mutex);
}
}
Compile and Run
gcc test.c -o test -lpthread
./test
Expected result
The main process is holding the lock...
The thread is holding the lock...
The main process is holding the lock...
The thread is holding the lock...
The main process is holding the lock...
The thread is holding the lock...
The main process is holding the lock...
...
Actual result
The main process is holding the lock...
The main process is holding the lock...
The main process is holding the lock...
The main process is holding the lock...
The main process is holding the lock...
The main process is holding the lock...
The main process is holding the lock...
...
Calls story in order
main -> [1] call lock (get the lock)
thread -> [2] call lock (waiting for main to unlock)
main -> [3] call unlock
thread -> [4] (still does not get the lock from [2], why? even though it has been unlocked?)
main -> [5] lock (get the lock again)
thread -> [6] (still does not get the lock from [2])
main -> [7] call unlock
thread -> [8] (still does not get the lock from [2], why? even though it has been unlocked?)
main -> [9] lock (get the lock again)
... and so on ...
Summary
pthread_mutex_lock does not guarantee the order of lock requests.