PROBLEMA Sincronizzazione processi tramite semafori

Pubblicità

federicofollini

Nuovo Utente
Messaggi
11
Reazioni
1
Punteggio
23
devo creare un sistema di sincronizzazione di processi in C seguendo questo schema:

PADRE:
Codice:
[crea i figli]
[riempie la memoria condivisa]
[da la possibilità ai figli di accedere alla memoria]

ho già creato il semaforo in questo modo
Codice:
struct sembuf * sops = (struct sembuf *) malloc (configs[0]*sizeof(struct sembuf));
int semid = semget(key_s, 1,  IPC_CREAT | IPC_EXCL | 0666);

    printf("modifico i semafori\n\n");
    sops[0].sem_num = 0;
    sops[0].sem_op = 1; 
    sops[0].sem_flg = 0;
    semop(semid, sops, 1);

e nel figlio ho recuperato il semaforo e fatto così:
Codice:
struct sembuf * sops = (struct sembuf *) malloc (1*sizeof(struct sembuf));  
    if((semid = semget(sem_key, 1, 0666)) == -1) {
        perror("semget");
        exit(1);
    }

    printf("Sono in attesa..\n\n");
    sops[0].sem_num = 0; 
    sops[0].sem_op = -1; 
    sops[0].sem_flg = 0;

    semop(semid, sops, 1);

Facendo così i figli mi stampano a video "sono in attesa", tuttavia non riesco a sbloccarli una volta che il padre ha erminato l'inserimento cei dati. come posso fare?
 
Ho un problema simile, di seguito ho riportato la mia soluzione a questo problema di sincronizzazione tra processi da risolvere con semafori. Mi piacerebbe ricevere un parere da qualcuno più esperto di me, in particolare sulle eventuali differenze tra Consumatore2() e Consumatore1() e se il codice può generare problemi di stallo o starvation. Grazie in anticipo!

Testo problema:
Si consideri il seguente problema di sincronizzazione tra processi formato da un processo produttore P e da due processi consumatore C1 e C2 , che condividono un’area di memoria (buffer) con 10 locazioni.
- Il processo produttore P genera ciclicamente un numero intero arbitrario e lo aggiunge al buffer di memoria condivisa. Il processo P si pone in attesa quando tenta di accedere al buffer pieno.
- Il processo C1 (C2) consuma ciclicamente un elemento del buffer. Il processo C1 (C2) può accedere al buffer solo se il buffer stesso non è vuoto, e può consumare un elemento del buffer solo se il numero attuale di elementi nel buffer stesso è dispari (pari).
Si proponga una soluzione con semafori al problema di sincronizzazione proposto. Si richiede la descrizione dei dati condivisi, lo pseudocodice delle procedure Produttore() e Consumatore1() e una discussione sulle eventuali differenze tra Consumatore2() e Consumatore1(). Si assuma l’esistenza delle procedure Genera(), Aggiungi_Al_Buffer(int x), Estrai_Dal_Buffer(), Consuma(int x), e Consuma_Buffer() con gli ovvi significati. Commentare la soluzione proposta e analizzare il suo comportamento rispetto ai problemi di deadlock e starvation.

SOLUZIONE:

#define size 10
int buffer [size];
semaforo vuote=size, piene=0, mutex=1, pari=0, disp=0;
int cont=0;

void produttore ()
{
int x;
do{
x=genera();
wait (vuote);
wait (mutex);
aggiungi_al_buffer(int x);
cont ++;
if (cont % 2 ==0) {
signal (pari);
disp.valore = 0;
}
else {
signal (dispari);
pari.valore = 0;
}
signal (mutex);
signal (piene);
} while (true);
}

void consumatore1 ()
{
do {
wait (piene);
wait (mutex);
estrai_dal_buffer ();
cont - - ;
signal (mutex);
signal (vuote);
wait (pari);
consuma (int x);
} while (true);
}
 
@federicofollini
Codice:
struct sembuf sops;
int semid = semget(key_s, 1,  IPC_CREAT | IPC_EXCL | 0666);

    printf("modifico i semafori\n\n");
    sops.sem_num = 0;
    sops.sem_op = 1;
    sops.sem_flg = 0;
    if(semop(semid, &sops, 1) == -1) {
       printf("Not good");
       exit(1);
   }

e nel figlio ho recuperato il semaforo e fatto così:
Codice:
struct sembuf sops;
    if((semid = semget(sem_key, 1, 0666)) == -1) {
        perror("semget");
        exit(1);
    }

    printf("Sono in attesa..\n\n");
    sops.sem_num = 0;
    sops.sem_op = -1;
    sops.sem_flg = 0;

    if (semop(semid, sops, 1) == -1)
       exit(1);

    printf("Sono entrato");
 
Ultima modifica:
Nel tuo caso, il testo dice che il produttore produce e basta. E' il figlio che deve controllare se possa mangiare o no.
Quindi, il produttore aggiunge se la coda non è piena, altrimenti aspetta.
Il consumatore aspetta che la coda non sia vuota, poi entra, prende un panino e aspetta che sia pari (dispari) per mangiare.
Riguardo la starvation, non ci son problemi: il padre produrrà e il figlio prima o poi mangierà senza aspettare eternamente.
Per il deadlock, bisogna prestare attenzione al fatto che se la coda massima è pari e il consumatore può mangiare solo quando è dispari c'è il rischio che il consumatore prenda il panino, subentri il padre che riempirà la coda e il figlio non potrà mai mangiare. Soluzione potrebbe essere che se la coda è piena il figlio mangi lo stesso, indipendentemente dal fatto che sia dispari o pari.
 
Pubblicità
Pubblicità
Indietro
Top