Che materia stai cercando?

Anteprima

ESTRATTO DOCUMENTO

}

} signal(semaphore

void s)

{ s.value++;

if (s.value<=0)

{ s.queue.remove(Process);

wake-up(Process);

}

}

Semaphore operations:

semid, *sops, nsops);

int semop(int struct sembuf unsigned

ognuno degli nsops elementi, riferiti dal puntatore sops, specifica ’operazione da compiere sul semaforo. L’operazione è descritta da

una struttura, struct sembuf.

wait

• sem_op < 0 : wait_for_zero

• sem_op==0 :

signal

• sem_op > 0 :

Rimozione di una struttura semaforica:

semctl(id_sem, num_sem ,IPC_RMID);

ne di una signal

La variabile num_sem in questo caso viene ignorata

Semafori Implementazione:

Ricorda che la struct sembuf contiene i seguenti campi:

unsigned short sem_num; // numero di semaforo

short sem_op; // operazione da compiere

short sem_flg; // flags

Wait_Sem(int,

static void int);

Signal_Sem

static void (int,int);

Queue_Sem

static int (int,int); //restituisce il num di processi in attesa su un semaforo

Wait_Sem(int

void 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

} Queue_Sem(int

int id_sem, int numsem)

{ return (semctl(id_sem,numsem,GETNCNT,NULL)); }

Signal_Sem

void (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

}

Monitor:

Permette la gestione di processi in base a delle condizioni, La sospensione di un processo nel caso in cui la

condizione non sia verificata, avviene utilizzando un nuovo tipo di variabile, detta variabile di tipo condition:

var_cond x;

sulla quale possono essere compiute signal e wait

x.wait; x.signal;

provoca la sospensione del processo fino a che un altro processo esegue

Ovviamente se non vi è alcun processo in attesa sulla variabile x, la signal non ha alcun effetto.

Signal and wait:

Sia P un processo sospeso su una variabile condition x e Q il processo che esegue la signal su tale variabile

Signal_and_wait prevede che il processo P risvegliato riprenda immediatamente l'esecuzione e che Q venga

sospeso;

Signal_and_urgent_wait:

Prevede che il processo Q abbia la priorità su ogni altro processo che intende entrare nel monitor Ciò si può

ottenere sospendendo il processo Q su un'apposita coda (urgent_queue).

Signal and continue:

detto anche wait and notify privilegia il processo segnalante rispetto al segnalato. Il processo Q segnalante

prosegue la sua esecuzione, mantenendo l'accesso esclusivo al monitor, dopo aver risvegliato P.

Il processo P segnalato viene trasferito alla coda associata all'ingresso del monitor,poiché in questa coda

possono esistere altri processi, questi possono precedere l'esecuzione di P e quindi modificare il valore della

condizione di sincronizzazione. P dovrà pertanto testare nuovamente la condizione di sincronizzazione prima

di proseguire.Quindi, con una politica signal_and_continue lo schema tipico di uso della primitiva wait è

all'interno di un while

while (!B) cond.wait()

<accesso alla risorsa>

Realizzazione di una var. condition:

CondVar

__________________

-condsem=0: semaphore

-condcount=0: int

__________________

+wait()

+signal()

Signal_and_wait (implementazione):

wait()

{condcount++;

signal(mutex);

wait(condsem); }

signal() {

condcount--;

signal(condsem);

wait(mutex); }

Signal_and_urgent_wait (implementazione):

wait() {

condcount++;

if (urgentcount>0)

signal(urgent);

else signal(mutex);

wait(condsem);

condcount--;}

signal() {

urgentcount++;

if condcount>0

{ signal(condsem);

wait(urgent);

}

urgentcount--;

}

Signal_and_continue (implementazione):

wait() {

condcount++;

signal(mutex);

wait(condsem);

wait(mutex);}

signal()

{ if condcount>0

{ condcount--;

signal(condsem);

}

}

Signal_and_return (supponendo che la signal sia l'ultima operazione):

wait() {

condcount++;

signal(mutex);

wait(condsem);

condcount--;}

signal() {

if (condcount>0)

signal(condsem);

else signal(mutex);}

Monitor, Implementazioni:

Due approcci: OB object-based (es linguaggio C) e OO object-oriented (es linguaggio C++)

Specifica del tipo monitor OB:

struct Monitor {

int mutex; //semaforo che garantisce la mutua esclusione

int num_var_cond; //numero di variabili condition

int id_conds; //id del gruppo di semafori associati alle var. cond.

int *cond_counts; //array delle variabili condition_count

int id_shared; //identificativo memoria condivisa

/*crea quindi un array di int (cond_counts)che indicano quanti processi ci sono in attesa su ognuna variabile condition ed inoltre crea

*un array di semafori (id_conds) associato alle variabili condition sul quale verranno effettuate le wait

}; init_monitor

void (Monitor*, int);

enter_monitor(Monitor*);

void leave_monitor(Monitor*);

void remove_monitor(Monitor*);

void wait_condition(Monitor*,int);

void signal_condition(Monitor*,int);

void

Specifica del tipo monitor OO:

Monitor {

class

private:

int mutex;

int num_var_cond;

int id_conds;

int *cond_counts;

int id_shared;

public:

Monitor(int);

virtual ~Monitor();

wait_condition(int);

void signal_condition(int);

void enter();

void leave();

void

};

Implementazione OB:

init_monitor

void (Monitor *M,int num_var){

M->num_var_cond=num_var;

M->mutex=semget(IPC_PRIVATE,1,IPC_CREAT|0664); //crea un array di 1 semaforo

M->id_conds=semget(IPC_PRIVATE,num_var,IPC_CREAT|0664); //crea un array di num_var semafori

semctl(M->mutex,0,SETVAL,1); //setta il valore del mutex a 0

for (int i=0;i<num_var;i++) //setta tutto l'array di num_var semafori a 0

semctl(M->id_conds,i,SETVAL,0);

M->id_shared=shmget(IPC_PRIVATE,num_var*sizeof(int),IPC_CREAT|0664); //alloca un contatore per ogni var.condition

M->cond_counts=(int*) (shmat(M->id_shared,0,0)); //effettua l'attach all'array di contatori appena allocato

for (int i=0;i<num_var;i++)

M->cond_counts[i]=0; // setta tutte le variabili condition a zero

/* In pratica è stata creata una memoria condivisa alla quale è collegato tramite il shmat(...) l'array di variabili condition cond_counts con un

* puntatore a int. Tutti gli elementi di questo array sono stati poi inizializzati a zero tramite il ciclo for.

*/

} wait_condition(Monitor*

void M,int id_var) //id_var indica l'elemento dell'array cond_counts sul quale effettuare la wait

{

M->cond_counts[id_var]=M->cond_counts[id_var]+1; // aggiunge 1 all'elemento cond_counts[id_var],ciò indica che c'è un processo

//in attesa sulla var. cond. Numero id_var

Signal_Sem(M->mutex,0); //effettua una signal sul mutex

Wait_Sem(M->id_conds,id_var); // effettua una wait sul semaforo dell'array id_conds di numero id_var.

M->cond_counts[id_var]=M->cond_counts[id_var]-1; // così diminuisce di 1 il conto dei processi sospesi sulla var. id_var

} signal_condition(Monitor*

void M,int id_var){

if(M->cond_counts[id_var]>0) // Se ci sono processi in attesa sulla var. cond. Indicata ne sblocca uno.

Signal_Sem(M->id_conds,id_var);

else //Altrimenti effettua una signal sul mutex

Signal_Sem(M->mutex,0);

/*Questa funzione dà precedenza ai processi in attesa sulla var. cond. Id_var , se non ce ne sono sblocca semplicemente il monitor*/

} enter_monitor(Monitor

void * M){

Wait_Sem(M->mutex,0);

} leave_monitor(Monitor*

void M){

Signal_Sem(M->mutex,0);

} remove_monitor(Monitor*

void M){

semctl(M->mutex,0,IPC_RMID); //Rimuove il mutex principale

semctl(M->id_conds,M->num_var_cond,IPC_RMID); //Rimuove l'array di semafori associato alle var. cond.

shmctl(M->id_shared,IPC_RMID,0); //Cancella la memoria condivisa. IMPORTANTE!!!

}

Scambio Di Messaggi:

Un messaggio é un blocco di informazioni, senza alcun formato predefinito,UNIX supporta il modello nel

quale lo scambio di messaggi avviene tra un utente e una mailbox (comunicazione indiretta)

Una mailbox può essere vista come una coda di messaggi.E' caratterizzata da:

• Una chiave (analoga a quella dei segmenti di memoria condivisa);

• Un proprietario (l’utente che la istanzia);

• Un gruppo di appartenenza;

• Un insieme di protezioni (indicate dalla solita stringa con 3 numeri a 3 bit)

Per instanziare una coda di messaggi

int msgget (key, flag)

restituisce l'ID della risorsa oppure -1

flag può valere IPC_CREAT | 0664 oppure 0 (se vogliamo utilizzare una coda già istanziata)

Esempio:

int open_queue( key_t keyval )

{ int qid;

if( (qid = msgget( keyval, IPC_CREAT | 0660 ) ) == -1)

return(-1);

return(qid);

}

Per inviare un messaggio alla mailbox

int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg)

Invia un messaggio sulla coda msqid. Il messaggio é contenuto all’interno del buffer msgbuf. Tale buffer ha

una struttura come la seguente (può essere ridefinita):

struct msgbuf

{ long message_type;

char message_text [MAX_SIZE];

}

Il campo message_type identifica il tipo del messaggio: esso diventa molto importante quando accoppiato con funzioni receive

selettive, perchè permette di estrarre un particolare messaggio dalla coda, anche se non si trova in cima

message_type

• Se assume il valore del pid del mittente possiamo realizzare una comunicazione indiretta simmetrica

message_text

• Il campo é una stringa Può essere sostituito con qualsiasi altro tipo di messaggio (intero, double, etc..)

msgsz

• Il campo rappresenta la dimensione (in byte) del messaggio da inviare

msgflg

• Il campo é un flag che ci permette di specificare la semantica dell’operazione di send

msgflg

• Se = 0 la send blocca il processo se la mailbox è piena

msgflg

• Se = IPC_NOWAIT la send ritorna -1 e non accoda il messaggio se la mailbox è piena

Esempio:

int result;

int msqid;

struct message {

long type;

char text[20];

} msg;

msg.type = 1;

strcpy(msg.text, "This is message 1");

result = msgsnd(msqid, (void *) &msg, sizeof(msg.text), IPC_NOWAIT);

Per ricevere un messaggio dalla mailbox

int msgrcv(int msqid, void *msgp, int msgsz, long msgtyp,int msgflg);

msqid

• Consuma un messaggio dalla mailbox identificata da

msgp

• Il buffer contenente il messaggio sarà puntato da msgsz

• Il campo messaggio di tale buffer avrà dimensione


ACQUISTATO

1 volte

PAGINE

12

PESO

225.10 KB

AUTORE

N. A.

PUBBLICATO

+1 anno fa


DETTAGLI
Corso di laurea: Corso di laurea in ingegneria informatica
SSD:
A.A.: 2013-2014

I contenuti di questa pagina costituiscono rielaborazioni personali del Publisher N. A. di informazioni apprese con la frequenza delle lezioni di Sistemi operativi e studio autonomo di eventuali libri di riferimento in preparazione dell'esame finale o della tesi. Non devono intendersi come materiale ufficiale dell'università Napoli Federico II - Unina o del prof Cotroneo Domenico.

Acquista con carta o conto PayPal

Scarica il file tutte le volte che vuoi

Paga con un conto PayPal per usufruire della garanzia Soddisfatto o rimborsato

Recensioni
Ti è piaciuto questo appunto? Valutalo!

Altri appunti di Sistemi operativi

Sistemi Operativi
Dispensa
Sistemi Operativi
Dispensa
Tesine sui sistemi operativi
Appunto
Sistemi operativi - Syscall atoi
Appunto