Vai alla Home Page About me Courseware Federica Living Library Federica Federica Podstudio Virtual Campus 3D Le Miniguide all'orientamento Gli eBook di Federica La Corte in Rete
 
I corsi di Ingegneria
 
Il Corso Le lezioni del Corso La Cattedra
 
Materiali di approfondimento Risorse Web Il Podcast di questa lezione

Domenico Cotroneo » 24.Esercitazione: System Call per la gestione dei semafori in Linux


Semafori: modello concettuale


Creazione ed inizializzazione di un semaforo

key_t chiave_sem=IPC_PRIVATE;
//richiesta di 2 semafori ed inizializzazione
sem=semget(chiave_sem,2,IPC_CREAT|0664);
//Inizializzazione dei due semafori
semctl(sem,0,SETVAL,val1);
semctl(sem,1,SETVAL,val2);

semop – semaphore operations

int semop(int semid, struct sembuf *sops, unsigned nsops);

Un semaforo è una struttura dati che comprende tra i suoi campi i seguenti:

unsigned short semval; /* semaphore value */
unsigned short semzcnt; /* # waiting for zero */
unsigned short semncnt; /* # waiting for increase */
pid_t sempid; /* process that did last op */

…è su questi che agisce la primitiva semop (in particolare sulla struttura indicata da semid).

semop – semaphore operations

Ognuno degli nsops elementi, riferiti dal puntatore sops, specifica un’operazione da compiere sul semaforo. L’operazione è descritta da una struttura, struct sembuf, la quale include i seguenti campi:

unsigned short sem_num; /* semaphore number */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */

Due sono i valori che puo’ assumere sem_flg: IPC_NOWAIT e SEM_UNDO. Se si specifica SEM_UNDO, l’operazione sarà annullata nel momento in cui il processo che la ha eseguita termina.

semop – semaphore operations

L’insieme delle operazioni specificate da sops sono eseguite in maniera atomica (le interruzioni saranno disabilitate).

Ogni operazione è eseguita sul semaforo individuato da sem_num (in altre parole sem_num indica su quale semaforo, tra quelli presenti nell’array, dovrà essere eseguita l’operazione).

Il primo semaforo dell’array ha indice 0.

I valori che può assumere il campo sem_op specificano tre possibili tipologie di operazioni che si possono compiere sul semaforo:

  • sem_op < 0 : wait
  • sem_op==0 : wait_for_zero
  • sem_op > 0 : signal

sem_op > 0: “signal”

Se sem_op è un intero positivo, l’operazione consiste nell’addizionare il valore di sem_op al valore del semaforo (semval).

semval+=sem_op

Inoltre, nel caso in cui sia specificato il flag SEM_UNDO, il sistema aggiornerà il contatore “undo count” (semadj) del processo per il semaforo in questione. E’ utile osservare che quest’ultima operazione non verrà mai bloccata.

Al fine di eseguire l’operazione di “signal”, il processo chiamante dovrà sicuramente avere i permessi necessari alla modifica dei valori del semaforo.

sem_op == 0: “wait_for_zero”

Se sem_op ha valore nullo, l’operazione specificata ( “wait-for-zero”) è articolata nei seguenti passi:

  1. se il valore semval è zero, l’operazione procede immediatamente (il processo non si sospende);
  2. altrimenti (semval ≠ 0) si procederà come di seguito:
    • se è specificato il flag IPC_NOWAIT in sem_flg, la system call fallisce restituendo il codice di errore EAGAIN a mezzo della variabile errno;
    • altrimenti la variabile semzcnt(che indica il numero di processi sospesi nell’attesa che il valore del semaforo diventi nullo) è incrementata di uno, forzando il processo a sopsendersi finché una delle seguenti condizioni si verificherà:
      • semval diventa 0, (allora il valore di semzcnt è decrementato);
      • il semaforo è rimosso: la system call fallisce ( errno = EIDRM).

Al fine di eseguire l’operazione di “wait_for_zero”, il processo chiamante dovrà almeno avere i permessi in lettura dei valori del semaforo.

sem_op < 0: “wait”

Se sem_op ha valore negativo, l’operazione si articolerà come di seguito:

  1. se (semval ≥ |sem_op| ) l’operazione procede immediatamente e se specificato il SEM_UNDO flag il sistema aggiornerà il contatore “undo count” (semadj) del processo per il semaforo in questione.
  2. se (semval < |sem_op| )
    • se specificato il flag IPC_NOWAIT la system call fallisce (errno = EAGAIN )
    • altrimenti il valore del campo semncnt (il contatore dei processi sospesi nell’attesa che il valore del semfaro venga incrementato) viene incrementato di 1. Il processo si sospende

Al fine di eseguire l’operazione di “wait”, il processo chiamante dovrà sicuramente avere i permessi necessari alla modifica dei valori del semaforo.

sem_op < 0: “wait”

Nel caso 2.2 il processo sarà sospeso nell’attesa del verificarsi di una delle seguenti condizioni:

1 ) (semval ≥ |sem_op| ), quando questa condizione sarà verificata il valore di semncnt sarà decrementato e il valore del semaforo sarà modificato come segue

semval-=|sem_op|

Se specificato SEM_UNDO il sistema aggiornerà il contatore “undo count” (semadj) del processo per il semaforo in questione.

2) Il semaforo è rimosso: la system call fallisce (errno = EIDRM).

Implementazione di una wait

void Wait_Sem (int id_sem, int numsem) {

struct sembuf sem_buf;
sem_buf.sem_num=numsem;
sem_buf.sem_flg=0;
sem_buf.sem_op=-1;
semop(id_sem,&sem_buf,1); //semaforo rosso

}

Implementazione di una signal

void Signal_Sem (int id_sem,int numsem) {

struct sembuf sem_buf;
sem_buf.sem_num=numsem;
sem_buf.sem_flg=0;
sem_buf.sem_op=1;
semop(id_sem,&sem_buf,1); //semaforo verde

}

  • Contenuti protetti da Creative Commons
  • Feed RSS
  • Condividi su FriendFeed
  • Condividi su Facebook
  • Segnala su Twitter
  • Condividi su LinkedIn
Progetto "Campus Virtuale" dell'Università degli Studi di Napoli Federico II, realizzato con il cofinanziamento dell'Unione europea. Asse V - Società dell'informazione - Obiettivo Operativo 5.1 e-Government ed e-Inclusion