Ciao, sono alle prese con un esercizio dove devo creare N processi con due diverse priorità(alta e bassa) che condividono K risorse equivalenti. I processi che utilizzano le risorse dovranno iniziare i rispettivi cicli di esecuzione tutti assieme. Ciascun processo ripete l'accesso ad una risorsa per N volte e per scegliere quale processo attivare tra quelli sospesi devo dare precedenza a quelli con priorità maggiore.
io ho scritto questo codice:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define K 5 /*numero massimo di risorse disponibili */
#define NUM_ITE 3 /*numero di iterazioni nella funzione usaRisorse*/
#define N1 4 /*processi di tipo A (priorità alta) */
#define N2 6 /*processi di tipo B (priorità bassa) */
#define N N1+N2 /*processi totali */
#define ritardo 3
typedef struct risorse{
int num_libere; //numero risorse utilizzabili
int disp[K]; //numero risorse disponibili
int sospesi[2]; //priorità (1)= alta, priorità(0)= bassa
}Risorse;
/*Dichiarazione variabili globali e condivise */
int shmid;
int mutex, semris,semprint;
Risorse *R;
/*variabili per la sospensione*/
int priv[2]; /*semaforo privato con priorità [prio] */
/*Funzione di inizializzazione dei campi della struttura risorse e dei semafori*/
void init(){
int i;
for(i=0;i<K;i++){
R->disp[i]=1; //tutte le risorse disponibili
}
R->num_libere= K; //tutte le risorse libere
R->sospesi[1]=R->sospesi[0]=0; //nessun processo sospeso
seminit(mutex, 0, 1);
seminit(semris, 0, K);
seminit(semprint, 0, 1);
seminit(priv[0],0,N1);
seminit(priv[1],0,N2);
}
// Funzione di stampa per la struttura Risorse
void printstatoris(){
printf("S--> Numero di risorse: %d\n", R->num_libere);
printf("S--> Numero di processi bloccati di priorità alta: %d\n", R->sospesi[1]);
printf("S--> Numero di processi bloccati di priorità bassa: %d\n",R->sospesi[0]);
}
int Cerca_Risorsa(){
int i=0;
int trovata=-1;
while ((i<K) && (trovata==-1)){ //esegue il ciclo finchè ci sono risose da controllare e non è stata trovata nessuna risorsa
if (R->disp[i]==1){ //se risorsa libera
trovata=i;
R->disp[i]=0; //risorsa impostata come occupata
}
i++;
}
return trovata;
}
// Funzione di acquisizione delle risorse
int Acquisisci(int priorita){
int id_risorsa;
down(mutex,0);
id_risorsa=Cerca_Risorsa(R);
if(id_risorsa==-1){ //nessuna risorsa disponibile
R->sospesi[priorita]++;
down(semprint,0);
printf("W--> Richiesta pendente del processo di priorità %d : %d che vuole ottenere una risorsa\n",priorita, getpid());
up(semprint, 0);
up(mutex, 0);
down(priv[priorita], 0);
down(mutex,0);
R->sospesi[priorita]--;
id_risorsa=Cerca_Risorsa();
up(mutex, 0);
down(semprint, 0);
printf("A-->Il processo di priorità %d con pid %d in attesa acquisisce la risorsa\n",priorita, getpid());
printstatoris();
up(semprint, 0);
}
down(semris, 0);
R->num_libere = R->num_libere--;
up(mutex, 0);
printf("stampa %d\n",id_risorsa);
return id_risorsa;
}
// Funzione di rilascio delle risorse
void Rilascia(int Res_id){
int j;
up(semris, 0);
down(mutex, 0);
R->disp[Res_id]=1; //rilascio risorsa impostandola a 1(libera)
R->num_libere = R->num_libere++;
down(semprint, 0);
printf("R--> Il processo con pid %d rilascia la risorsa...\n",getpid());
printstatoris(R);
up(semprint, 0);
if(R->sospesi[1]>0)
up(priv[1],0);
else if(R->sospesi[0]>0)
up(priv[0],0);
else
up(mutex,0);
}
// Funzione per l'esecuzione di NUM_ITE delle funzioni Acquisisci e Rilascia, ritardate nel mezzo dalla chiamata di sistema sleep()
void UsaRisorsa(int priorita){
int i;
int Res_id;
for(i=0; i<NUM_ITE;i++){
Res_id=Acquisisci(priorita);
printf("valore %d\n", semprint);
waitz(semris,0); //attendo che tutti i processi che utilizzano una risorsa inizino insieme
sleep(ritardo);
Rilascia(Res_id);
}
}
main(){
int n,i;
int p1=1;
int p0=1;
if ((shmid = shmget(IPC_PRIVATE,sizeof(Risorse),0600)) == -1) perror("Creazione memoria condivisa");
if ((semris = semget(IPC_PRIVATE,1,0600)) == -1) perror("Creazione semaforo semris");
if ((priv[0] = semget(IPC_PRIVATE,1,0600)) == -1) perror("Creazione semaforo privato priorità bassa");
if ((priv[1] = semget(IPC_PRIVATE,1,0600)) == -1) perror("Creazione semaforo privato priorità alta");
if ((mutex = semget(IPC_PRIVATE,1,0600))==-1)perror("Creazione semaforo mutex");
if ((semprint = semget(IPC_PRIVATE,1,0600))==-1)perror("Creazione semaforo semprint");
R = (Risorse*) shmat(shmid, NULL, 0);
init();
printf("Risorse iniziali disponibili: %d\n", R->num_libere);
while ((p1+p0)<N){
if(p1<=N1){
if (fork()==0){
UsaRisorsa(1); //priorità alta
p1++;
exit(0);
}
}
if(p0<=N2){
if (fork()==0){
UsaRisorsa(0); //priorità bassa
p0++;
exit(0);
}
}
}
for(i=0;i<N1;i++){
n=wait(0);
down(semprint, 0);
printf("Terminato processo %d\n",n);
up(semprint, 0);
}
for(i=0;i<N2;i++){
n=wait(0);
down(semprint, 0);
printf("Terminato processo %d\n",n);
up(semprint, 0);
}
printf("Risorse finali disponibili: %d\n", R->num_libere);
if(semctl(semris,0,IPC_RMID)==-1) perror("Rimozione semaforo semris");
if(semctl(priv[0],0,IPC_RMID)==-1) perror("Rimozione semaforo privato");
if(semctl(priv[1],0,IPC_RMID)==-1) perror("Rimozione semaforo privato");
if(semctl(mutex,0,IPC_RMID)==-1) perror("Rimozione semaforo mutex");
if(semctl(semprint,0,IPC_RMID)==-1) perror("Rimozione semaforo semprint");
if(shmctl(shmid,IPC_RMID,NULL)==-1) perror("Rimozione memoria condivisa");
}
Il file collegato con le funzioni richiamate è il seguente:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int waitz(int semid, int semnum)
/* attesa del valore zero sulla componente semnum di semid */
{
int r;
struct sembuf sb;
sb.sem_num=semnum;
sb.sem_op=0;
sb.sem_flg=0;
r=semop(semid,&sb,1);
if (r==-1) perror("semop in attesa");
return r;
}
int down(int semid, int semnum)
/* operazione DOWN sulla componente semnum di semid */
{
int r;
struct sembuf sb;
sb.sem_num=semnum;
sb.sem_op=-1;
sb.sem_flg=0;
r=semop(semid,&sb,1);
if (r==-1) perror("semop in down");
return r;
}
int up(int semid, int semnum)
/* operazione UP sulla componente semnum di semid */
{
int r;
struct sembuf sb;
sb.sem_num=semnum;
sb.sem_op=1;
sb.sem_flg=0;
r=semop(semid,&sb,1);
if (r==-1) perror("semop in up");
return r;
}
int seminit(int semid, int semnum, int initval)
/* inizializzazione con initval della componente semnum di semid */
{
int r;
#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
/* union semun is defined by including <sys/sem.h> */
#else
/* according to X/OPEN we have to define it ourselves */
union semun {
int val; /* value for SETVAL */
struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* array for GETALL, SETALL */
/* Linux specific part: */
struct seminfo *__buf; /* buffer for IPC_INFO */
};
#endif
union semun arg;
arg.val=initval;
r=semctl(semid,semnum,SETVAL,arg);
if (r==-1) perror("semop in up");
return r;
}
Non capisco cosa continuo a sbagliare, mi va sempre in loop. Se riuscite ad aiutarmi...
Grazie!!!!!