Salve a tutti sono alle prime armi nella programmazione
ho un problema nell'implementazione del codice (dopo 10 cicli riga 68) il programma crasha dandomi il seguente errore
/nptl/pthread_mutex_lock.c:352: __pthread_mutex_lock_full: Assertion `INTERNAL_SYSCALL_ERRNO (e, __err) != ESRCH || !robust' failed.
Aborted
ps non penso sia il solo errore
grazie in anticipo per qualsiasi consiglio suggerimento
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<pthread.h>
#include<semaphore.h>
#define carta 0
#define contanti 1
#define contanti_e_carta 2
#define biglietti_tot 2000 //numero di biglietti totati disponibili per l'evento
#define rivenditori_n 10 //numero di rivenditori disponibili
#define lotto_l 20 // numero di biglietti disponibile presso ogni rivenditore
#define acquisto_max 8 //numero massimo di biglietti acquistabili per ogni cliente
#define numero_clienti 200 // numero di clienti
typedef struct Rivenditore{
int n_biglietti;
int pagamento;
int id;
int count;
pthread_t tid;
pthread_mutex_t lock;
pthread_cond_t disponibili;
pthread_cond_t ultimati;
} Rivenditore;
typedef struct Cliente{
int n_biglietti;
int pagamento;
int id;
pthread_t tid;
Rivenditore* r;
}Cliente;
int biglietti_posseduti_rivenditore;
sem_t lockrivenditori;
int counter_cliente;
Cliente* set_cliente(int n_biglietti, int id, Rivenditore* r );
void* acquista(void*arg);
void check(int x);
void init(Rivenditore* r);
void* vendita(void* arg);
void transazione(Cliente c);
int main(){
Rivenditore r[rivenditori_n];
init(r);
for(int i=0;i<rivenditori_n;i++){
pthread_create(&r[i].tid,NULL,vendita,(void*) &r[i]);
}
while(counter_cliente<numero_clienti){
Cliente *c;
c=set_cliente(rand()%acquisto_max+1,counter_cliente,&r[rivenditori_n%counter_cliente]);
if(c->pagamento!=carta)
pthread_setschedprio(c->tid,120);
else pthread_setschedprio(c->tid,90);
pthread_create(&c->tid,NULL,acquista,(void*) c);
sleep(1);
printf("contatore clienti %d\n",counter_cliente);
printf("\ntest %d\n",rivenditori_n%counter_cliente);
counter_cliente++;
}
for(int i=0;i<rivenditori_n;i++)
pthread_join(r[i].tid,NULL);
printf("biglietti totali rivenditore %d\n",biglietti_posseduti_rivenditore);
return 0;
}
void* acquista(void* arg){
Cliente* c;
c=(Cliente*) arg;
check(pthread_mutex_lock(&c->r->lock));
while(c->r->n_biglietti==0)
pthread_cond_wait(&c->r->ultimati,&c->r->lock); // se i biglietti disponibili sono finiti aspetta
while(c->r->n_biglietti<c->n_biglietti){ // se i biglietti disponibili sono inferiori a quelli richiesti diminuisco la richiesta
c->n_biglietti--;
}
c->r->n_biglietti-= c->n_biglietti; //aggiorno i biglietti disponibili
transazione(*c);
printf("%lu sta acquistando %d biglietti dal venditore %d ed gli sono rimasti %d\n",pthread_self(),c->n_biglietti,c->r->id,c->r->n_biglietti);
if(c->r->n_biglietti==0 && c->r->count!=rivenditori_n) // se i biglietti sono finiti faccio una signal
pthread_cond_signal(&c->r->disponibili);
check(pthread_mutex_unlock(&c->r->lock));
return NULL;
}
void* vendita(void * arg){
Rivenditore* r;
r=(Rivenditore*)arg;
while(biglietti_posseduti_rivenditore<biglietti_tot && r->count<rivenditori_n){ //ogni rivenditore non puo acquistare piu di un tot biglietti
sem_wait(&lockrivenditori);
check(pthread_mutex_lock(&r->lock));
while(r->n_biglietti>0) //se i biglietti non sono stati completamente venduti mi metto in attesa
pthread_cond_wait(&r->disponibili,&r->lock);
r->count++;
r->n_biglietti+=lotto_l;
biglietti_posseduti_rivenditore+=lotto_l;// il rivenditore acquistano solo lotti di biglietti
printf("il rivenditore %d ha acquistato un lotto di biglietti biglietti disponibili %d\n",r->id,r->n_biglietti);
//if(r->count!=0)
pthread_cond_broadcast(&r->ultimati); //risveglio i clienti in attessa
check(pthread_mutex_unlock(&r->lock)); //rilascio il mutex tra rivenditore e cliente
sem_post(&lockrivenditori);
}
return NULL;
}
void transazione(Cliente c){
if(c.pagamento==carta)
sleep(rand()%2);
else sleep(rand()%3+1);
}
void init(Rivenditore* r){
for(int i=0;i<rivenditori_n;i++){
r[i].n_biglietti=0;
r[i].id=i;
r[i].count=0;
pthread_mutex_init(&r[i].lock,NULL);
pthread_cond_init(&r[i].ultimati,NULL);
pthread_cond_init(&r[i].disponibili,NULL);
}
sem_init(&lockrivenditori,0,1);
counter_cliente=1;
biglietti_posseduti_rivenditore=0;
}
Cliente* set_cliente(int n,int id, Rivenditore* r){
Cliente* x=malloc(sizeof(Cliente));
if(x==NULL){
fprintf(stderr,"errore malloc /n");
exit(-1);
}
if(r->pagamento==contanti_e_carta)
x->pagamento=rand()%2;
else x->pagamento=r->pagamento;
x->id=id;
x->n_biglietti=n;
x->r=r;
return x;
}
void check(int x){
if(x!=0){
fprintf(stderr," errore %d\n",x);
exit(-1);}
}