Robust Mutex


/*
 * Exemplo de uso de mutexes robustos
 * No exemplo no_robust saímos da thread sem liberarmos o lock que efetuamos no mutex.
 * Resultado a outra thread, fica sempre "trancada" no mutex. Provocando um deadlock.
 *
 * No segundo caso, setamos nosso mutex com a propriedade de ser "robusto". Ou seja, se uma thread
 * acabar - por um sigsegv por exemplo - vamos conseguir "destravar" nosso mutex
 * e podemos continuar o que estamos fazendo.
 *
 * Para compilar: gcc main.c -pthread
 * Para executar: ./a.out
 */
#define __USE_GNU
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <error.h>

pthread_mutex_t mutex;
pthread_mutexattr_t attr;
int counter = 0;

void mythread_no_robust(void){
 int i;
 for (i=0; i < 10000; i++){
 pthread_mutex_lock(&mutex);
 counter ++;
 if(counter > 200)
 pthread_exit(NULL);
 pthread_mutex_unlock(&mutex);
 }
 pthread_exit(NULL);
}

void mythread_robust(void){
 int i, ret;
 for (i=0; i < 10000; i++){
 ret = pthread_mutex_lock(&mutex);
 switch(ret){
 case 130:
 pthread_mutex_consistent(&mutex);
 break;
 case 131:
 pthread_mutex_destroy(&mutex);
 pthread_mutexattr_setrobust_np (&attr, PTHREAD_MUTEX_ROBUST_NP);
 pthread_mutex_init (&mutex, &attr);
 break;

default:// printf("\n\tValue of ret: %d", ret);
 break;
 }
 counter ++;
 if(counter > 200)
 pthread_exit(NULL);
 pthread_mutex_unlock(&mutex);
 }
 pthread_exit(NULL);
}
int main_no_robust(void){
 pthread_t t1,t2;
 pthread_create(&t1, NULL, (void *)&mythread_no_robust, NULL);
 pthread_create(&t2, NULL, (void *)&mythread_no_robust, NULL);
 pthread_join(t1, NULL);
 pthread_join(t2, NULL);
 printf("\n\tValue of Counter: %d\n", counter);
 return 1;
}

int main_robust(void){
 pthread_mutexattr_init (&attr);
 pthread_mutexattr_setrobust_np (&attr, PTHREAD_MUTEX_ROBUST_NP);
 pthread_mutex_init (&mutex, &attr);
 pthread_t t1,t2;
 pthread_create(&t1, NULL, (void *)&mythread_robust, NULL);
 pthread_create(&t2, NULL, (void *)&mythread_robust, NULL);
 pthread_join(t1, NULL);
 pthread_join(t2, NULL);
 printf("\n\tValue of Counter: %d\n", counter);
 return 1;
}

int main(){

int opt = 0;
 printf("\n\t0 - No robust\n\t1 - Robust\n\tOpt:\t");
 scanf("%d", &opt);
 switch(opt){
 case 0: main_no_robust(); break;
 case 1: main_robust(); break;
 }

return 1;
}

Deixe uma resposta