Anteprima
Vedrai una selezione di 10 pagine su 41
Tesine sui sistemi operativi Pag. 1 Tesine sui sistemi operativi Pag. 2
Anteprima di 10 pagg. su 41.
Scarica il documento per vederlo tutto.
Tesine sui sistemi operativi Pag. 6
Anteprima di 10 pagg. su 41.
Scarica il documento per vederlo tutto.
Tesine sui sistemi operativi Pag. 11
Anteprima di 10 pagg. su 41.
Scarica il documento per vederlo tutto.
Tesine sui sistemi operativi Pag. 16
Anteprima di 10 pagg. su 41.
Scarica il documento per vederlo tutto.
Tesine sui sistemi operativi Pag. 21
Anteprima di 10 pagg. su 41.
Scarica il documento per vederlo tutto.
Tesine sui sistemi operativi Pag. 26
Anteprima di 10 pagg. su 41.
Scarica il documento per vederlo tutto.
Tesine sui sistemi operativi Pag. 31
Anteprima di 10 pagg. su 41.
Scarica il documento per vederlo tutto.
Tesine sui sistemi operativi Pag. 36
Anteprima di 10 pagg. su 41.
Scarica il documento per vederlo tutto.
Tesine sui sistemi operativi Pag. 41
1 su 41
D/illustrazione/soddisfatti o rimborsati
Disdici quando
vuoi
Acquista con carta
o PayPal
Scarica i documenti
tutte le volte che vuoi
Estratto del documento

Produttore/Consumatore utilizzando le primitive send e receive per la comunicazione mediante code di messaggi (Costruzione di un protocollo sincrono mediante le primitive di scambio di messaggi asincrone)

Descrizione: Il programma seguente risolve il problema dei Produttori/Consumatori implementando un protocollo sincrono di comunicazione che fa uso delle primitive (asincrone) messe a disposizione dal sistema. Occorre fare in modo che produttore e consumatore si sincronizzino opportunamente in modo da non perdere il messaggio da scambiare. A tal fine produttore e consumatore, prima dell'invio del messaggio effettivo, si scambiano dei messaggi di sincronizzazione secondo lo schema seguente:

Produttore Consumatore

Invia messaggio di pronto ad inviare In attesa di messaggio di pronto ad inviare

In attesa di messaggio di pronto a ricevere Invio messaggio di pronto a ricevere

Invio del messaggio effettivo In attesa del messaggio effettivo

Ovvero, in termini di Send Asincrona a Receive.

Bloccante...Produttore Consumatore
Send asincrona(coda, "pronto ad inviare")
Receive bloccante(coda, pronto ad inviare)
Receive bloccante(coda, pronto a ricevere)
Send asincrona(coda, "pronto a ricevere")
Send asincrona(coda, "messaggio")
Receive bloccante(coda, messaggio)
Nell'implementazione proposta viene utilizzata una sola coda differenziando nel contempo il tipo di messaggi.
Programma VII.C

#include <sys/types.h>
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>
#define DIM_MSG 256 //Cardinalità del Messaggio
#define Ready_To_Send 0 //Tipi di Messaggio...
#define Ready_To_Receive 1
#define Data_Message 2
typedef struct { //Definizione del Messaggio
    long tipo;
    char testo[DIM_MSG];
} Messaggio;
void main() {
    pid_t pid; //Variabili locali
    int i;
    int status;
    Messaggio RS,RR,DM; //Messaggi: Ready To Send, Ready to Receive, Data Message
    //----- ALLOCAZIONE CODA DI MESSAGGI -----
    key_t
Key_Msg=IPC_PRIVATE; //Chiave della coda di messaggi
int ID_Msg; //Identificatore della coda di messaggi
ID_Msg=msgget(Key_Msg, IPC_CREAT|0664); //Viene allocata una coda di messaggi, le viene associato
//un ID e viene creata una struttura dati ausiliaria che
//consenta di gestirla, con i seguenti permessi
//RW per User, RW per Gruppo, R only per Others
if (ID_Msg==-1) {
    perror("MSGGET\n"); //In caso di errore...
    exit(-1);
}

//----- GENERAZIONE FIGLIO PRODUTTORE -----
pid=fork(); //Generazione del figlio Produttore
if (pid==-1) {
    perror("Impossibile creare un nuovo processo\n"); //In caso di errore...
    exit(-1);
} else if (!pid) { //Codice del figlio Produttore
    printf("Sono il Produttore, PID = %d\n", getpid());
    RS.tipo=Ready_To_Send;
    strcpy(RS.testo, "Ready_To_Send");
    msgsnd(ID_Msg, (const void*)&RS, DIM_MSG, 0);
    printf("Produttore: Ho inviato il Ready To Send\n");
    printf("Produttore: Sono in attesa del Ready To Receive\n");
    msgrcv(ID_Msg,
(const void*)&RR, DIM_MSG, Ready_To_Receive, 0);
if (!strcmp((const char*)RR.testo, "Ready To Receive")) {
    DM.tipo=Data_Message;
    strcpy(DM.testo, "Hello!");
    msgsnd(ID_Msg, (const void*)&DM, DIM_MSG, 0);
    printf("Produttore: Ho inviato il Messaggio\n");
}
exit(0); //Il figlio Produttore termina correttamente
}

//----- GENERAZIONE FIGLIO CONSUMATORE -----
pid=fork(); //Generazione del figlio Consumatore
if (pid==-1) {
    perror("Impossibile creare un nuovo processo\n"); //In caso di errore...
    exit(-1);
} else if (!pid) { //Codice del figlio Consumatore
    printf("Sono il Consumatore, PID = %d, in attesa del Ready To Send\n", getpid());
    msgrcv(ID_Msg, (const void*)&RS, DIM_MSG, Ready_To_Send, 0);
    if (!strcmp((const char*)RS.testo, "Ready To Send")) {
        printf("Consumatore: Ho ricevuto il Ready to Send\n");
        RR.tipo=Ready_To_Receive;
        strcpy(RR.testo, "Ready To Receive");
        msgsnd(ID_Msg, (const void*)&RR, DIM_MSG,
0);
printf("Consumatore: Ho inviato il Ready To Receive e sono in attesa del Messaggio\n");
msgrcv(ID_Msg, (const void*)&DM, DIM_MSG, Data_Message, 0);
printf("Consumatore: Messaggio ricevuto!\n");
}
exit(0); //Il figlio Consumatore termina correttamente
}

//----- SINCRONIZZAZIONE DEL PADRE CON I FIGLI -----
for(i=0; i<2; i++) { //Il padre rimane in attesa che i figli terminino...
pid=wait(&status);
printf("Il figlio con PID %d è terminato!\n",pid);
}

//----- RILASCIO CODA DI MESSAGGI -----
msgctl(ID_Msg, IPC_RMID, 0);
}

19Problemi di cooperazione nel modello a scambio di messaggi

Scrivere una applicazione concorrente che implementi uno schedulatore di processiVIII)che gestisce tre livelli di priorità usando le code di messaggi.

Descrizione: Il programma seguente mostra come è possibile implementare uno schedulatore di processi usando lecode di messaggi. Un processo utente che voglia essere schedulato deve inviare allo schedulatore un

Il tuo compito è formattare il testo fornito utilizzando tag html.

ATTENZIONE: non modificare il testo in altro modo, NON aggiungere commenti, NON utilizzare tag h1;

messaggiodi tipo Ready_To_Be_Scheduled, indicando in esso la propria priorità e il proprio PID, dopodiché si pone inattesa, da parte dello schedulatore, di un messaggio di tipo Ready_To_Schedule_You che gli comunichi che èstato scelto: a questo punto il processo eseguirà il suo carico di istruzioni e prima di terminare invierà alloscheduler un messaggio di tipo End_of_Execute, segnalando in tal modo di aver concluso il proprio lavoro. Piùin generale, lo scheduler esegue ciclicamente il polling (receive non bloccante) di una coda dei messaggi (si èscelto per semplicità di usare una sola coda) alla ricerca di una richiesta di schedulazione, analizzando lerichieste disponibili sulla base della priorità dichiarata dai singoli processi e scegliendo il prossimoprocesso da schedulare: letto il PID del messaggio prescelto, gli viene inviato un messaggio di attivazione.Fatto ciò, non gli resta che porsi in attesa della

Segnalazione di terminazione del processo schedulato

Segnalazione di terminazione del processo schedulato, dopo la quale potrà riprendere a svolgere da capo la propria attività. Si noti che, nell'implementazione proposta, il processo padre è lo scheduler dei processi figli.

Programma VIII.C

#include <sys/types.h>
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>

#define DIM_MSG (sizeof(unsigned int)) // Cardinalità del Messaggio
#define Urgent 0 // Tipi del Messaggio...
#define Normal 1
#define Idle 2
#define End_of_Execute 3
#define Ready_To_Schedule_You (long)100000

typedef struct { // Definizione del Messaggio
    long tipo;
    unsigned int PID;
} Messaggio;

#define N_PROC 5 // Numero di processi da schedulare

void main() {
    pid_t pid; // Variabili locali
    int i;
    int status, found, priority, myPID;
    Messaggio msg;

    // ----- ALLOCAZIONE CODA DI MESSAGGI -----
    key_t Key_Msg = IPC_PRIVATE; // Chiave della coda di messaggi
    int ID_Msg; // Identificatore della coda di messaggi

    ID_Msg = msgget(Key_Msg, 

IPC_CREAT|0664); //Viene allocata una coda di messaggi, le viene associato
//un ID e viene creata una struttura dati ausiliaria che
//consenta di gestirla, con i seguenti permessi
//RW per User, RW per Gruppo, R only per Others
if (ID_Msg==-1) {
    perror("MSGGET\n"); //In caso di errore...exit(-1);
}

//----- GENERAZIONE DEI FIGLI DA SCHEDULARE -----
for(i=0; i<N_PROC; i++) {
    pid=fork(); //Generazione del figlio i-esimo
    if (pid==-1) {
        perror("Impossibile creare un nuovo processo\n"); //In caso di errore...exit(-1);
    } else if (!pid) { //Codice del figlio
        myPID=getpid(); //Definisce propri PID e priorità
        priority=int(rand()) % 3;
        printf("Sono il figlio con PID %d e priorità %d\n", myPID, priority);
        sleep(int(rand()) % 5); //Attende un tempo casuale da 1 a 5 secondi
        //prima di richiedere che venga schedulato
        msg.tipo=priority;
        msg.PID=myPID;
        msgsnd(ID_Msg, (const void*)&msg, DIM_MSG, 0); //Invia la richiesta di schedulazione
        msgrcv(ID_Msg, (const void*)&msg,


DIM_MSG, (myPID+Ready_To_Schedule_You), 0);//Attende che lo scheduler invii un messaggio che//abbia come TIPO esattamente il suo PID sommato//alla costante Ready_To_Schedule_You
printf("Processo %d in Esecuzione...\n", myPID); //Simulazione di esecuzione...
sleep(1);
msg.tipo=End_of_Execute;
msgsnd(ID_Msg, (const void*)&msg, DIM_MSG, 0); //Comunica allo scheduler la sua terminazione
exit(0); //Il figlio i-esimo termina correttamente
20
}} //End For ... N_PROC

//----- SCHEDULAZIONE DEI FIGLI -----
for (i=0; i<N_PROC; i++) {
    priority=1;
    found=0;
    while (!found) {
        if (msgrcv(ID_Msg, (const void*)&msg, DIM_SG, priority, IPC_NOWAIT)!=-1) found=1;
        else priority=(priority+1) % 3;
    } //Almeno un processo ha richiesto//la schedulazione...
    printf("Mando in esecuzione il processo con PID %d e priorità %d\n", msg.PID, priority);
    msg.tipo = msg.PID + Ready_To_Schedule_You;
    msgsnd(ID_Msg, (const void*)&msg, DIM_MSG, 0); //Avvia l'esecuzione del processo//appena schedulato
    msgrcv(ID_Msg,

(const void*)&msg, DIM_MSG, End_of_Execute, 0); //Rimane in attesa che tale//processo schedulato gli comunichi//la sua terminazione}
//----- SINCRONIZZAZIONE DEL PADRE CON I FIGLI (ormai Zombie) -----
for(i=0; i<N_PROC; i++) pid=wait(&status); //I figli sono già terminati tutti e//sono attualmente Zombie...
//----- RILASCIO CODA DI MESSAGGI -----
msgctl(ID_Msg, IPC_RMID, 0);}

Problemi di cooperazione nel modello a scambio di messaggi

Si realizzi un processo che riceve messaggi da altri processi mediante una coda di messaggi e risponde con un intero che dice quanti messaggi sono stati ricevuti fino a quel momento. Per la comunicazione delle risposte si deve usare la stessa coda di messaggi delle richieste. La coda di messaggi deve essere creata dal primo processo che ne fa uso, non necessariamente il servente.

Descrizione: Il programma seguente mostra come è possibile implementare una comunicazione multidirezionale tra processi utilizzando una singola coda di messaggi.

Il processo padre genera un certo numero di processi figli: tra questi viene casualmente designato un processo server mentre tutti gli altri divengono client. Il primo (fra tutti i processi figli) che entra in azione (dopo un tempo casuale) alloca la coda di messaggi e gli altri si limitano ad usarla. Inoltre, ciascun processo client invia un messaggio di HELLO sulla coda e attende una risposta dal server, affinché gli comunichi quanti messaggi sono stati fino a quel momento inviati sulla coda, dopodiché termina.

Dettagli
Publisher
A.A. 2012-2013
41 pagine
SSD Scienze matematiche e informatiche INF/01 Informatica

I contenuti di questa pagina costituiscono rielaborazioni personali del Publisher cecilialll 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 De Carlini Riccardo.