Hari
Hari

Reputation: 175

Will a thread waiting on a mutex get the ownership, immediately after mutex_unlock() by other thread?

I have two threads - threadA & threadB. If B is waiting for mutex, which is owned by A, Will it get the ownership immediately after A unlocks it, assuming it has higher priority than A ?
This not a question on who gets the lock when multiple threads are waiting, but if a single waiting thread becomes runnable & gets the processor or not.

From the test example below it doesn't seem to happen always. Can someone please clarify ?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

//global variables
/* START = THREAD A runs, STOP = THREAD A Stops & Waits */
volatile enum { START, STOP } state = START;
pthread_cond_t      condA  = PTHREAD_COND_INITIALIZER;
pthread_mutex_t     mutex = PTHREAD_MUTEX_INITIALIZER;

void *threadA()
{
int i = 0;
int j = 0;

struct sched_param p;
p.sched_priority                        =       16;
pthread_setschedparam(pthread_self(), SCHED_FIFO, &p);

printf("threadA created\n");
while(1)
{
    printf("threadA lock requested  \n");
    pthread_mutex_lock(&mutex);
    while (state == STOP)
    {
        printf("Waiting in STOP state, until some one sends START again\n");
        pthread_cond_wait(&condA, &mutex);
    }
    printf("threadA locked mutex  \n");
    //do stuff - ~a few ms of work, simulated with dummy for loop
    for(j=0; j<=100000000; j++)
        ;
    i++;
    printf("threadA loop cntr %d\n",i);
    //printf("threadA   unlock requested  \n");
    pthread_mutex_unlock(&mutex);
    printf("threadA unlocked mutex  \n");
}
fflush(stdout);
return 0;
}

void *threadB()
{

struct sched_param p;
p.sched_priority                        =       17;
pthread_setschedparam(pthread_self(), SCHED_FIFO, &p);

printf("threadB created\n");
do
{
    /* Time to stop threadA */
    printf("threadB lock requested  \n");
    pthread_mutex_lock(&mutex);
    printf("threadB locked mutex  \n");
    state = STOP;
    pthread_cond_signal(&condA);
    //printf("threadB unlock requested  \n");
    pthread_mutex_unlock(&mutex);
    //printf("threadB unlocked mutex  \n");
}while(0);
fflush(stdout);
return 0;
}

int main(int argc, char *argv[])
{
int j = 0;

//create our threads
pthread_t a, b;

pthread_create(&a, NULL, threadA, NULL);
/* Wait for a while to make sure A is 
   up & running before stopping it */
for(j=0; j<=100000; j++)
    ;
// Now stop A
pthread_create(&b, NULL, threadB, NULL);

fflush(stdout);


pthread_join(a, NULL);
pthread_join(b,NULL);
}

Typical output I see is as below..
threadA created
threadA lock requested
threadA locked mutex
threadB created
threadB lock requested
threadA loop cntr 1
threadA unlocked mutex << A unlocked it, so a waiting B should receive it here??
threadA lock requested
threadA locked mutex
threadA loop cntr 2
threadB locked mutex << B granted ownership finally !!
threadA unlocked mutex
threadA lock requested
Waiting in STOP state, until some one sends START again

Upvotes: 4

Views: 1785

Answers (1)

Andrew Henle
Andrew Henle

Reputation: 1

Simply put: no, you can not rely in any way on which waiting thread will get a mutex, or even that a waiting thread will be woken up before another thread that wasn't waiting for the mutex happens to request and get the lock.

In fact, the OS scheduler might even be more likely to allow an already-running thread to continue to run and obtain the lock.

Upvotes: 7

Related Questions