Вам нужно заставить init
взять указатель на указатель на мьютекс для инициализации. В настоящее время глобальный mtx
не изменился.
Вот примерно как:
void init(pthread_mutex_t **mtx){ // pointer to pointer
*mtx=malloc(N*sizeof(pthread_mutex_t)); // dereference
if(!*mtx){
perror("malloc fallita\n");
exit(EXIT_FAILURE);
}
for(int i=0;i<N;i++){
if(pthread_mutex_init(&(*mtx)[i],NULL) != 0){ // pointer acrobatics
perror("init fallita\n");
exit(EXIT_FAILURE);
}
}
}
и затем передайте указатель на глобальный mtx
в main
:
int main(void){
init(&mtx);
Я предлагаю по-разному называть ваш глобальный мьютекс и ваш локальный мьютекс в init
, чтобы это вас больше не смущало.
Кроме того, прямо здесь вы передаете значение i
как void *
вместо передачи его адреса:
if(pthread_create(&th[i],NULL,filosofo,(void*)(intptr_t)i) != 0){
Если вы сделаете это (что я действительно рекомендую избегать условий гонки), то вам следует изменить filosofo
, чтобы принимать данные таким же образом :
unsigned int id = (unsigned int)arg;