Saturday, December 1, 2012

What happens if a pthread holding mutex lock exits without unlocking?

This was question asked by someone. It was kind of new to me :-). It was very good question indeed. So what is the answer? Let me write a simple C code.


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

pthread_mutex_t nasty_mutex = PTHREAD_MUTEX_INITIALIZER;

void*
pthread_mutex_function (void *arg)
{
    pthread_mutex_lock(&nasty_mutex);
    printf("Got my lock ;)\n");
    pthread_mutex_unlock(&nasty_mutex);
}

void*
pthread_mutex_nasty_function (void *arg)
{
    pthread_mutex_lock(&nasty_mutex);
}

int main (void)
{
    pthread_t tid[3];
    int i=0;

    pthread_create(&tid[0], NULL, pthread_mutex_nasty_function, NULL);
    pthread_create(&tid[1], NULL, pthread_mutex_function, NULL);
    pthread_create(&tid[2], NULL, pthread_mutex_function, NULL);

    for (; i<3; i++) {
        pthread_join(tid[i], NULL);
    }
}

So what is the output? LOL :D deadlock. This is really nasty coding. I thought LWP state would be cleared even if thread exits however, that is not case. The cleanup happens after process exits not LWP. Conclusion is that we have to make sure nothing crashes when holding lock, that does not mean it should crash after releasing mutex lock ;). For me it was one more learning.

Code tested in Linux mint 14 /64 bit. Validations in code are left to user!

Edit 1: I did mention that thread should not crash while holding a lock. But if the lock is private to process, then entire process address space goes for toss after crash. This will not lead to any deadlocks ;-). However, if thread exits gracefully without releasing lock, then consequences are obvious. I am not sure what happens if the mutex lock is shared across processes and the process holding lock crashes. I will give a try sometimes later when I get time.