2
votes

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

1
"After" isn't really a well-defined notion.Kerrek SB
Have you checked that your pthread_setschedparam() calls are not returning an error?caf
Yes, pthread_setschedparam() calls are successfull. I am running it as sudoHari
Running a program via sudo does not guarantee that the calls are successful. You can only check that they're successful by capturing the return value and handling non-zero values as errors.Jonathan Leffler

1 Answers

5
votes

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.