#include #include #include #include pthread_mutex_t lock; void* f_thread1(void *v) { pthread_mutex_lock(&lock); /* Dorme para que a thread2 execute o unlock antes da thread1 e assim possamos ilustrar a situação de erro. */ sleep(2); if (pthread_mutex_unlock(&lock) == EPERM) { printf("Erro não esperado.\n"); } else { printf("Unlock efetuado com sucesso.\n"); } return NULL; } void* f_thread2(void *v) { /* Faz com que a thread2 execute o unlock depois do lock efetuado pela thread1. */ sleep(1); /* Mutexes do tipo RECURSIVE também verificam no momento do unlock se a thread que está executando o unlock é a mesma que executou o lock. Caso isto seja verdadeiro, a função pthread_mutex_lock retorna imediatamente EPERM, sinalizando o erro para quem a chamou. */ if (pthread_mutex_unlock(&lock) == EPERM) { printf("Unlock de mutex que foi lockado por outra thread.\n"); } return NULL; } int main() { pthread_t thr1, thr2; /* Este exemplo inicializa o mutex utilizando as funções de configuração de atributos. Os atributos são do tipo pthread_mutexattr_t e devem ser inicializados através da função pthread_mutexattr_init. O tipo do mutex pode ser configurado através da função pthread_mutexattr_settype. */ pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP); pthread_mutex_init(&lock, &attr); pthread_create(&thr1, NULL, f_thread1, NULL); pthread_create(&thr2, NULL, f_thread2, NULL); pthread_join(thr1, NULL); pthread_join(thr2, NULL); printf("Finalizando programa\n"); return 0; }