IMC!


Contenuti


Foto

 







Curiosando...
Novita  Novità Link  Link Blog  Blog English  Español 
03 - Sincronizzazione di processi con semafori

 | 

I semafori sono un altro strumento, oltre ai segnali, a disposizione dei programmatori per sincronizzare i processi. A differenza dei segnali possono essere visti come una sorta di variabile in comune ai vari programmi lei cui proprietà possono essere modificate durante l'esecuzione. Queste elementi richiedono l'uso di tre librerie:
  1. sys/types.h
  2. sys/ipc.h
  3. sys/sem.h
Le principali funzioni di gestione dei semafori sono:
  1. semget (key_t key, int num_sem, short flags): La funzione crea un gruppo di semafori, che viene identificato con un numero positivo intero. I semafori dentro al gruppo sono identificati partendo a contare da 0 con numeri crescenti positivi.

    • key: è una chiave necessaria per la generazione del set di semafori; può essere un numero qualsiasi, ma per essere sicuri che non vi siano duplicati si può usare ftok(), studiata apposta. Se tale valore vale IPC_PRIVATE, la creazione dei semafori è forzata.
    • num_sem: indica il numero di semafori appartenenti al gruppo.
    • flags: indica gli attributi del gruppo di semafori: IPC_CREAT crea i semafori. IPC_EXCL verifica che i semafori esistano. E' possibile specificare anche comandi di impostazione dei permessi.
    Riassumento, le condizioni per cui la creazione di un gruppo di semafori va a buon fine sono:

    • L'uso di una chiave non duplicata e la presenza del flag IP_CREAT.
    • L'uso, come chiave, del comando IPC_PRIVATE.
  2. semctl(int semid, int semnum, int cmd, union argomenti): esegue una operazione cmd su un semaforo semnum di un gruppo semid. Le operazioni sono:

    • IPC_RMID: rimuove il set di semafori.
    • GETVAL: legge il valore di un semaforo.
    • SETVAL: imposta il valore di un semaforo.
    • GETPID: ottiene il PID dell'ultimo processo che ha usato il semaforo.
    Se è necessario passare alla funzione dei valori, può essere fatto con l'unione argomenti, in particolare SETVAL e GETVAL.
  3. semop (int sem_id, struct sembuf *operation, int num_elements): esegue una operazione sui semafori. Le operazioni possibili sono:

    • sem_id: indica il gruppo di semafori.
    • operation: vettore che indica su quale semaforo agire e quale operazione effetturare. E' composto da tre elementi:

      • sem_num: numero del semaforo all'interno del gruppo
      • sem_op: operazione da eseguire. Se sem_op è negativo, viene eseguita una wait(). Se sem_op è positivo viene eseguita una signal().
      • sem_flg: utilizzato per compiere operazioni particolari, tra cui:

        • SEM_UNDO: quando il processo termina, imposta il semaforo al suo vecchio valore
        • IPC_NOWAIT: non sospende il processo, ma restituisce -1.
    • num_elements: indica il numero di elementi allocati per il vettore operation.
Di seguito c'è un esempio che mostra le principali operazioni eseuibili con i semafori.

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/errno.h>
#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
/* L'unione semun è già definita in <sys/sem.h> */
#else
/* Secondo X/OPEN dobbiamo definire semun da soli */
union semun {
  int val; /* Valore per SETVAL */
  struct semid_ds *buf; /* buffer per IPC_STAT, IPC_SET */
  unsigned short int *array; /* array per GETALL, SETALL */
  struct seminfo *__buf; /* buffer per IPC_INFO */
} pippo; // Alloco la unione semun
#endif

struct sembuf pluto; // Alloco la struttura pluto di tipo sembuf

main()
{
  int semaforo;
  semaforo = semget(IPC_PRIVATE, 1, 0777);
  if(semaforo > 0)
  {
    printf("Creato il semaforo: %d\n", semaforo);
    printf("Sto per leggere il semaforo\n");
    semctl(semaforo,0,GETALL,&pippo);
    printf("Valore: %d\n",pippo.val);
    printf("Sto per impostare il valore del semaforo a 3\n");
    pippo.val = 3;
    semctl(semaforo,0,SETVAL,pippo);
    printf("Sto per leggere il semaforo\n");
    semctl(semaforo,0,GETALL,&pippo);
    printf("Valore: %d\n",pippo.val);
    pluto.sem_num = 0;
    pluto.sem_op = -1;
    printf("Attesa sul semaforo\n");
    semop(semaforo,&pluto,1);
    printf("Sto per leggere il semaforo\n");
    semctl(semaforo,0,GETALL,&pippo);
    printf("Valore: %d\n",pippo.val);
    pluto.sem_num = 0;
    pluto.sem_op = 1;
    printf("Segnale sul semaforo\n");
    semop(semaforo,&pluto,1);
    printf("Sto per leggere il semaforo\n");
    semctl(semaforo,0,GETALL,&pippo);
    printf("Valore: %d\n",pippo.val);
  }
}


 | 







Commenti

Nessun commento presente!

Scrivi un commento

Pui scrivere quì sotto un commento all'articolo che hai appena letto. Non sono abilitate smile, immagini e link. La lunghezza massima del commento è 4000 caratteri. La buona educazione è benvenuta, tutti i commenti offensivi saranno cancellati.

Your comment (lascia bianco!):
Utente (max 25 caratteri, obbligatorio)
Sito web (max 255 caratteri, facoltativo)
e-Mail (max 255 caratteri, facoltativa, non sarà pubblicata) Your opinion (lascia bianco!):
Commento (max 4000 caratteri, obbligatorio):





Valid HTML 4.01 Transitional
E-Mail - 15.19 ms

Valid HTML 4.01 Transitional