Anteprima
Vedrai una selezione di 4 pagine su 12
Sistemi operativi - schema suntivo per la prova pratica Pag. 1 Sistemi operativi - schema suntivo per la prova pratica Pag. 2
Anteprima di 4 pagg. su 12.
Scarica il documento per vederlo tutto.
Sistemi operativi - schema suntivo per la prova pratica Pag. 6
Anteprima di 4 pagg. su 12.
Scarica il documento per vederlo tutto.
Sistemi operativi - schema suntivo per la prova pratica Pag. 11
1 su 12
D/illustrazione/soddisfatti o rimborsati
Disdici quando
vuoi
Acquista con carta
o PayPal
Scarica i documenti
tutte le volte che vuoi
Estratto del documento

Implementazioni dei metodi Signal e Wait

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

Implementazioni del tipo monitor OB:

struct Monitor {
    int mutex;
    // altre variabili e metodi del monitor
};
```html

//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_monitorvoid (Monitor*, int);

enter_monitor(Monitor*);

void leave_monitor(Monitor*);

void remove_monitor(Monitor*);

void wait_condition(Monitor*,int);

void signal_condition(Monitor*,int);

voidSpecifica 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();

};

Implementazione OB:

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

<!-- Sblocca semplicemente il monitor -->
enter_monitor(Monitor* M){
    Wait_Sem(M->mutex,0);
}

leave_monitor(Monitor* M){
    Signal_Sem(M->mutex,0);
}

remove_monitor(Monitor* 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. È 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 istanziare una coda di messaggi, utilizziamo la funzione msgget(key, flag). Questa funzione restituisce l'ID della risorsa oppure -1 se si verifica un errore. Il parametro flag può assumere il valore IPC_CREAT | 0664 se vogliamo creare una nuova coda di messaggi, 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, utilizziamo la funzione msgsnd(msqid, msgp, msgsz, msgflg). Questa funzione invia un messaggio sulla coda msqid. Il messaggio è contenuto all'interno del buffer msgbuf. La struttura del buffer è la seguente:

struct msgbuf {
  long message_type;
  char message_text[MAX_SIZE];
}

Il campo message_type identifica il tipo del messaggio. Questo campo diventa molto importante quando utilizziamo funzioni di ricezione selettive, perché ci permette di estrarre un particolare messaggio dalla coda anche se non si trova in cima.

Se il campo message_type assume il valore del PID del mittente, possiamo realizzare una...

  • Il campo è una stringa. Può essere sostituito con qualsiasi altro tipo di messaggio (intero, double, etc..)
  • Il campo rappresenta la dimensione (in byte) del messaggio da inviare
  • Il campo è un flag che ci permette di specificare la semantica dell'operazione di send
  • Se = 0 la send blocca il processo se la mailbox è piena
  • 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à dimensionemsgtyp• Il campo (tipo del messaggio) svolge importanti funzioni:msgtyp• Se = 0 viene prelevato il primo messaggio della coda (ovvero quello inviato da più tempo);msgtyp msgtyp• Se > 0 viene prelevato il primo messaggio dalla coda il cui campo tipo sia pari al valore dimsgtyp |msgtyp|• Se < 0 viene prelevato il primo messaggio dalla coda il cui campo tipo abbia una valore minore o uguale amsgflg• Il campo se impostato a 0 indica una ricezione bloccante: se non ci sono messaggi da consumare nella mailbox, il processomsgrcvsi sospende sulla fino al giungere del messaggio. Se impostato a IPC_NOWAIT, la ricezione non é bloccante: se non ci sonomessaggi viene restituito -1

Esempio:

int result;
int msqid;
struct message {
    long type;
    char text[20];
} msg;
long msgtyp = 0;
result = msgrcv(msqid, (void *) &msg, sizeof(msg.text),msgtyp, IPC_NOWAIT);

Primitiva di controllo

int msgctl(int msqid,
int cmd, struct msqid_ds *buf); cmd: L'operazione da eseguire dipende dal valore di cmd che può valere: - IPC_STAT per la lettura della coda senza consumo - IPC_SET per modificare le caratteristiche della coda - IPC_RMID per la deallocazione Posix Threads: Per la creazione di un Thread utilizzare la funzione pthread_create: pthread_create(thread, attr, start_r, arg) - thread (output): di tipo pthread_t, è un identificatore del thread creato - attr (input): di tipo pthread_attr_t, serve a settare gli attributi del thread - start_r (input): puntatore (di tipo void*) alla funzione C (starting routine) che verrà eseguita una volta che il thread è creato - Firma di una starting routine di esempio: void* foo(void*) - arg (input): argomento (di tipo void*) che può essere passato alla funzione C (ne va fatto il casting a void*) Per il passaggio di parametri nella creazione di un thread si usa la variabile arg che consente di passare un valore di tipo void*.singolo argomento di tipo void *; Per passare più di un argomento al thread, si può definire e passare una struct, facendone il casting a void *: ```html struct dati { int dato1; char dato2; }; dati *d; d->dato1 = 10; d->dato2 = 'c'; pthread_create(&id, NULL, start_f, (void *) d) ``` Nel thread sarà sufficiente effettuare il casting inverso: ```html dati* miei_dati = (struct dati *) d; ``` Per la terminazione di un Thread: - La starting routine termina la sua esecuzione: `pthread_exit(status);` (status) - Il thread chiama la funzione `pthread_cancel();` dove è lo stato di uscita del Thread - L'intero processo termina. Per la creazione e distruzione di Mutex: ```html pthread_mutex_init(mutex, attr) ``` Crea un nuovo mutex e lo inizializza come "sbloccato" (unlocked). - mutex (output): di tipo pthread_mutex_t è un identificatore del mutex creato - attr (input): per settare gli attributi del mutex. <mutex> <pthread_mutex_destroy> (mutex) Distrugge un mutex che non serve più. </pthread_mutex_destroy> <pthread_mutex_lock> (mutex) Un thread invoca la lock su un mutex per acquisire l'accesso in mutua esclusione alla sezione critica relativa al mutex. </pthread_mutex_lock> </mutex>
Dettagli
Publisher
A.A. 2012-2013
12 pagine
2 download
SSD Scienze matematiche e informatiche INF/01 Informatica

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à Università degli studi di Napoli Federico II o del prof Cotroneo Domenico.