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);
  }
}


 | 






Fatal error: Call to undefined function sqlite_open() in /membri/giacobbe85/include/commenti.inc.php on line 324