Poiché nel sistema operativo VxWorks
tutti i task esistono nello stesso spazio degli indirizzi, è evidente
che ogni variabile globale risulta automaticamente condivisa tra tutti
i task. Se da un lato questa caratteristica rende semplice lo scambio
delle informazioni tra i task, dall'altro impone l'adozione di un
meccanismo che impedisca l'accesso contemporaneo in scrittura di tali
variabili così da evitare l'inconsistenza dei dati.
Il sistema più efficiente rendere esclusivo l'accesso alle risorse condivise, consiste nell'utilizzare un semaforo binario.
Il primo passo consiste nel creare il semaforo binario come disponibile (pieno):
/* includes */
#include "vxWorks.h"
#include "semLib.h"
SEM_ID semMutex;
/* Crea un semaforo binario disponibile (pieno). I task
* in attesa sul semaforo acquisiscono il semaforo a seconda
* della loro priorità.
*/
semMutex = semBCreate (SEM_Q_PRIORITY, SEM_FULL);
Ogni
volta che un task vuole accedere alla risorsa condivisa, deve prima
acquisire il semaforo creato in precedenza e rilasciarlo ed alla fine
delle operazioni:
semTake (semMutex, WAIT_FOREVER);
.
. /*
. * regione critica accessibile solo da un task
. * alla volta
. */
.
semGive (semMutex);
I
semafori binari possono essere utilizzati efficacemente anche per
sincronizzare l'esecuzione di due o più task; in questo caso il
semaforo rappresenta la condizione di attesa del task da sincronizzare.
Il semaforo è creato come non disponibile (vuoto) ed è utilizzato per
bloccare l'esecuzione del task che deve essere sincronizzato, un
secondo task, quando si verifica la condizione o l'evento atteso,
rilascia il semaforo permettendo al primo task di proseguire la sua
esecuzione.
/*
* Questo esempio mostra l'impiego dei semafori per la
* sincronizzazione di 2 task.
*/
/* includes */
#include "vxWorks.h"
#include "semLib.h"
SEM_ID syncSem; /* ID of sync semaphore */
init( )
{
/* creazione del semaforo */
syncSem = semBCreate (SEM_Q_FIFO, SEM_EMPTY);
/* Creazione del task che solleva l'evento. */
taskSpawn ("esempio1", 100, 0, 20000, task1,
0,0,0,0,0,0,0,0,0,0);
/* Creazione del task da sincronizzare. */
taskSpawn ("esempio2", 101, 0, 20000, task2,
0,0,0,0,0,0,0,0,0,0);
}
task1 (void)
{
...
/* Permette al task 2 di processare l'evento */
semGive (syncSem);
...
}
task2 (void)
{
...
/* attende il verificaresi dell'evento */
semTake (syncSem, WAIT_FOREVER);
printf ("Il task 2 ha ottenuto il semaforo\n");
... /* elaborazione dell'evento */
}
Se
più task dovvessero essere sbloccati a seguito di un evento, il task
che solleva l'evento di sincronizzazione può sfruttare la funzione semFlush(), che sblocca tutti i task in attesa di uno stesso semaforo.
Vota questo articolo per primo
- Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5