Как правильно уничтожить pthread mutex
Как именно я могу уничтожить переменную мьютекса pthread?
Вот что я хочу сделать. Я хочу кэшировать объекты (структурные переменные), которые ищутся по ключу. Я хочу, чтобы здесь была минимальная степень детализации замков. Поэтому я хочу иметь блокировку для каждого объекта, вероятно, встроенную в структуру, чтобы иметь возможность блокировки на уровне объекта.
Теперь проблема в том, как безопасно уничтожить эти объекты? Похоже, что первым шагом является удаление объекта из таблицы поиска, чтобы в будущем этот объект был недоступен, и это нормально.
Я хочу освободить объект из кэша. Теперь, как правильно уничтожить / освободить мьютекс? Документ pthread_mutex_destroy говорит, что мы не должны использовать pthread_mutex_destroy, пока мьютекс заблокирован. Допустим, поток решает уничтожить объект, необходимый для уничтожения блокировки, поэтому снимает блокировку и выполняет pthread_mutex_destroy. Что происходит с другими потоками, ожидающими блокировки объектов?
Вот код для симуляции выше, обратите внимание, что я использовал sleep (2), чтобы усилить эффект гонки.
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
typedef struct exampleObj {
pthread_mutex_t mutex;
int key;
int value1;
int value2;
}exampleObj;
exampleObj sharedObj = {PTHREAD_MUTEX_INITIALIZER,0,0,0};
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
exampleObj* Lookup(int key) {
return &sharedObj;
}
void* thrFunc(void* id) {
int i = (*((int*)id));
char errBuf[1024];
exampleObj * obj = Lookup(0);
if (pthread_mutex_lock(&obj->mutex)) {
printf("Locking failed %d \n",i);
return NULL;
}
// Do something
printf("My id %d will do some work for 2 seconds.\n",i);
sleep(2);
pthread_mutex_unlock(&obj->mutex);
int errNum = pthread_mutex_destroy(&obj->mutex);
strerror_r(errNum,errBuf,1024);
printf("Destroying mutex from thread %d : %s\n ",errNum,errBuf);
return NULL;
}
int main() {
pthread_t thrds[10];
int i;
int args[10];
char errBuf[1024];
int errNum = 1;
for (i=0;i<10;i++){
args[i] = i;
pthread_create(&thrds[i],NULL,thrFunc,args+i);
}
for (i=0;i<10;i++){
pthread_join(thrds[i],NULL);
}
return 0;
}
Несколько потоков успешно уничтожают мьютекс. А остальные темы зависают навсегда. GDB показывает, что эти потоки ожидают блокировки.