Ciao a tutti, come da titolo sto cercando di realizzare un programma produttore-consumatore con più produttori, più consumatori, un pool di buffer il cui accesso è regolamentato da un vettore di stato (libero/occupato/in uso) e un monitor. (il tutto in ubuntu)
Il monitor l'ho realizzato così:
codice:
typedef struct{
int mutex;
int urgent_sem;
int num_cond;
int id_cond;
int id_shm;
int * p_cond;
int * p_urgent;
} Monitor;
codice:
void init_monitor(Monitor * M,int n_var){
M->num_cond = n_var;
M->mutex = semget(IPC_PRIVATE,1,IPC_CREAT|0664);
semctl(M->mutex,0,SETVAL,1);
M->urgent_sem = semget(IPC_PRIVATE,1,IPC_CREAT|0664);
semctl(M->urgent_sem,0,SETVAL,0);
M->id_cond = semget(IPC_PRIVATE,n_var,IPC_CREAT|0664);
int i;
for(i=0;i<n_var;i++)
semctl(M->id_cond,i,SETVAL,0);
M->id_shm = shmget(IPC_PRIVATE,sizeof(int)*(n_var+1),IPC_CREAT|0664);
M->p_cond = (int *) shmat(M->id_shm,0,0);
M->p_urgent = n_var + M->p_cond;
for(i=0;i<n_var;i++)
M->p_cond[i] = 0;
*(M->p_urgent) = 0;
}
void enter_monitor(Monitor * M){
sem_wait(M->mutex,0);
}
void leave_monitor(Monitor * M){
if(*(M->p_urgent)>0)
sem_signal(M->urgent_sem,0);
else
sem_signal(M->mutex,0);
}
void wait_condition(Monitor * M, int n_var){
M->p_cond[n_var]=M->p_cond[n_var]+1;
if(*(M->p_urgent)>0)
sem_signal(M->urgent_sem,0);
else sem_signal(M->mutex,0);
sem_wait(M->id_cond,n_var);
M->p_cond[n_var]=M->p_cond[n_var]-1;
}
void signal_condition(Monitor * M, int n_var){
(*(M->p_urgent))++;
if(M->p_cond[n_var]>0){
sem_signal(M->id_cond,n_var);
sem_wait(M->urgent_sem,0);
}
(*(M->p_urgent))--;
}
La parte che non ho capito riguarda come realizzare produttori e consumatori. Ho provato a fare una cosa di questo tipo:
codice:
typedef struct{
int ok_produzione;
int ok_consumo;
int accesso_produzione;
int accesso_consumo;
int test;
int vet_stato[DIM_BUFFER]; //0=libero | 1=in_uso | 2=occupato
int buffer[DIM_BUFFER];
Monitor M;
} MonitorPC;
codice:
void Produttore(MonitorPC * MPC){
enter_monitor(&(MPC->M));
if(MPC->ok_produzione==0)
wait_condition(&(MPC->M),OK_PRODUZIONE);
printf("prod iniziata\n");
int i=0;
bool trovato=false;
if(MPC->accesso_produzione==0)
wait_condition(&(MPC->M),MUTEXP);
while(!trovato&&i<DIM_BUFFER)
if(MPC->vet_stato[i]==LIBERO)
trovato=true;
else i++;
MPC->vet_stato[i]=IN_USO;
signal_condition(&(MPC->M),MUTEXP);
//sleep(1+rand()%3);
int messaggio = rand()%10;
wait_condition(&(MPC->M),MUTEXP);
MPC->buffer[i] = messaggio;
MPC->vet_stato[i] = OCCUPATO;
printf("Valore %d prodotto e inserito in posizione %d\n", messaggio,i);
signal_condition(&(MPC->M),MUTEXP);
MPC->ok_produzione--;
MPC->ok_consumo++;
signal_condition(&(MPC->M),OK_CONSUMO);
leave_monitor(&(MPC->M));
}
Ma è sicuramente sbagliato. Suggerimenti?