Il sistema operativo LINUX Semafori 2 Sommario Sommario Select
Transcript
Il sistema operativo LINUX Semafori 2 Sommario Sommario Select
Sistemi operativi – Modulo II I semafori 2 Il sistema operativo LINUX Semafori 2 Sommario • Select – Esempio • Tema d’esame Giorgio Di Natale <[email protected]> Stefano Di Carlo <[email protected]> Politecnico di Torino Dip. Automatica e Informatica Sommario • Select – Esempio • Tema d’esame Select • La system call read è bloccante • Non è possibile eseguire contemporaneamente una wait su due semafori (se si utilizza la read) • La system call select restituisce l’informazione relativa allo stato di un insieme di file Select Select #include <sys/time.h> #include <sys/types.h> #include <unistd.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> int select( int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); int select( int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); G. Di Natale, S. Di Carlo Set di file descriptor sbloccanti quando effettuano una lettura 1 Sistemi operativi – Modulo II I semafori 2 Select #include <sys/time.h> #include <sys/types.h> #include <unistd.h> Set di file descriptor sbloccanti quando effettuano una scrittura int select( int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); Select #include <sys/time.h> #include <sys/types.h> #include <unistd.h> Set di file descriptor sbloccanti quando int select( int n, generano un errore fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); Select Select #include <sys/time.h> Massimo file descriptor #include <sys/types.h> all’interno dei 3 set #include <unistd.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> int select( int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); int select( int n, fd_set *readfds, fd_set *writefds, Timeout fd_set *exceptfds, struct timeval *timeout); Select – Funzionamento • La select è bloccante fino a quando: – un file nel set di file descriptor in lettura effettua una lettura, oppure – un file nel set di file descriptor in scrittura effettua una scrittura, oppure – un file nel set di file descriptor in errore genera un errore, oppure – Scade il timeout G. Di Natale, S. Di Carlo Select – Funzionamento • Quando la select si sblocca, nei file descriptor set rimangono solo i file che hanno avuto una variazione di stato 2 Sistemi operativi – Modulo II I semafori 2 Select – Valore di ritorno • La select restituisce il numero di file descriptor che hanno avuto una variazione dello stato. Timeout • Il timeout viene specificato con precisione al micro secondo: struct timeval { time_t tv_sec; time_t tv_usec; } Sommario • Select – Esempio • Tema d’esame G. Di Natale, S. Di Carlo Gestione dei set • FD_ZERO (fd_set *set) – Inizializza un nuovo set • FD_SET (int fd, fd_set *set) – Inserisce un file descriptor nel set • FD_CLR (int fd, fd_set *set) – Elimina un file descriptor da un set • FD_ISSET (int fd, fd_set *set) – Restituisce 1 se il file descriptor è nel set Timeout - Nota • Per effettuare la system call sleep con precisione al micro secondo, è possibile chiamare la select con i tre file descriptor set vuoti Esempio • Scrivere un programma che legga da due pipe contemporaneamente. 3 Sistemi operativi – Modulo II #include #include #include #include <sys/time.h> <sys/types.h> <unistd.h> <stdio.h> I semafori 2 Esempio Esempio if (f!=0) { /* Padre */ while (1) { printf ("Invio a write (pipe2[1], sleep (3); printf ("Invio a write (pipe1[1], sleep (3); } int main() { int pipe1[2], pipe2[2]; int f; fd_set fds; char buf; int max, r; pipe (pipe1); pipe (pipe2); f = fork(); } else { /* Figlio */ FD_ZERO (&fds); FD_SET (pipe1[0], &fds); FD_SET (pipe2[0], &fds); max = (pipe1[0]>pipe2[0]?pipe1[0]:pipe2[0])+1; while (1) { r=select (max, &fds, NULL, NULL, NULL); if (FD_ISSET(pipe1[0], &fds)) { read (pipe1[0], &buf, 1); printf ("Ricevuto da pipe1.\n"); FD_SET (pipe2[0], &fds); } else { read (pipe2[0], &buf, 1); printf ("Ricevuto da pipe2.\n"); FD_SET (pipe1[0], &fds); } } } return 0; pipe1.\n"); "C", 1); } else { /* Figlio */ FD_ZERO (&fds); FD_SET (pipe1[0], &fds); FD_SET (pipe2[0], &fds); max = (pipe1[0]>pipe2[0]?pipe1[0]:pipe2[0])+1; while (1) { r=select (max, &fds, NULL, NULL, NULL); if (FD_ISSET(pipe1[0], &fds)) { read (pipe1[0], &buf, 1); printf ("Ricevuto da pipe1.\n"); FD_SET (pipe2[0], &fds); } else { read (pipe2[0], &buf, 1); printf ("Ricevuto da pipe2.\n"); FD_SET (pipe1[0], &fds); } } } return 0; Esempio } pipe2.\n"); "C", 1); Esempio } Sommario • Select – Esempio • Tema d’esame G. Di Natale, S. Di Carlo Problema • Si implementi in linguaggio C un programma che realizzi 10 processi “treno”. • Ogni treno t percorre una sua linea ferroviaria LE(t) ed entra in una stazione S con un solo binario. • Dalla stazione escono le linee LU(1), LU(2), LU(3) ed LU(4). • Un treno non può entrare in stazione provenendo dalla linea LE(k) se la stazione e’ occupata oppure se la linea di uscita che il treno richiede per proseguire il suo viaggio non è libera. 4 Sistemi operativi – Modulo II I semafori 2 Problema Analisi del problema • Un treno arriva alla stazione ad intervalli di tempo casuali, decide di proseguire su una linea LU scelta a caso, e la occupa per un numero casuale di secondi. • Quando la stazione viene liberata da un treno e più treni sono in attesa di entrare viene fatto procedere quello che arriva dalla linea di entrata con indice più basso. Stazione Soluzione Soluzione Stazione Stazione Id del treno + Binario uscita Id del treno + Binario uscita Soluzione Stazione Binario uscita Id del treno + Binario uscita G. Di Natale, S. Di Carlo 5