Difference between revisions of "Prova Pratica 18-06-2015"
Jump to navigation
Jump to search
(Created page with "==Esercizio1== <source lang="text"> Usando signalfd (e non signal o sigaction) scrivere due programmi tx e rx. Rx deve essere attivato per primo e per prima cosa stampa il suo...") |
|||
Line 158: | Line 158: | ||
printf("\n"); | printf("\n"); | ||
return 0; | return 0; | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | ==Esercizio2== | ||
+ | |||
+ | <source lang="text"> | ||
+ | Si costruiscano due programmi txtime e rxnull per stimare l'efficienza di tx e rx. | ||
+ | Rxnull e' uguale all'rx precedente ma non stampa nulla. | ||
+ | Txtime ha come parametri il pid del ricevente e un numero intero n. Txtime deve spedire n caratteri 'K' al txtnull e alla fine deve stampare | ||
+ | il tempo medio impiegato per spedire un carattere. | ||
+ | </source> | ||
+ | |||
+ | <source lang="c"> | ||
+ | // Esercizio2: txtime | ||
+ | |||
+ | #include <stdlib.h> | ||
+ | #include <stdio.h> | ||
+ | #include <string.h> | ||
+ | #include <signal.h> | ||
+ | #include <unistd.h> | ||
+ | #include <errno.h> | ||
+ | #include <sys/types.h> | ||
+ | #include <sys/signalfd.h> | ||
+ | |||
+ | #include <sys/timeb.h> | ||
+ | |||
+ | #define EXIT_WITH_ERROR(function) \ | ||
+ | { \ | ||
+ | printf("Error %i in ",errno); \ | ||
+ | printf(function); \ | ||
+ | printf(": %s\n",strerror(errno)); \ | ||
+ | exit(EXIT_FAILURE); \ | ||
+ | } | ||
+ | |||
+ | int main(int argc, char *argv[]) | ||
+ | { | ||
+ | pid_t rx; | ||
+ | int n; | ||
+ | int j; | ||
+ | |||
+ | // variabili per calcolare il tempo medio di trasmissione | ||
+ | struct timeb time_start, time_end; | ||
+ | int millisec; | ||
+ | float media; | ||
+ | |||
+ | sigset_t mask; | ||
+ | int sfd; | ||
+ | struct signalfd_siginfo siginfo; | ||
+ | |||
+ | if(argc != 3) | ||
+ | { | ||
+ | printf("Usage: Tx rx string\n"); | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | if(sscanf(argv[1],"%i",&rx) != 1) | ||
+ | EXIT_WITH_ERROR("sscanf"); | ||
+ | if(sscanf(argv[2],"%i",&n) != 1) | ||
+ | EXIT_WITH_ERROR("sscanf"); | ||
+ | |||
+ | ftime(&time_start); | ||
+ | |||
+ | // setto il sigset_t a contenere SIGUSR1 (sara' l'acknowledgement) | ||
+ | sigemptyset(&mask); | ||
+ | sigaddset(&mask, SIGUSR1); | ||
+ | |||
+ | // annullo l'azione standard per SIGUSR1 | ||
+ | if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) | ||
+ | EXIT_WITH_ERROR("sigprocmask") | ||
+ | |||
+ | sfd = signalfd(-1, &mask, 0); | ||
+ | if (sfd == -1) | ||
+ | EXIT_WITH_ERROR("signalfd"); | ||
+ | |||
+ | // invio n caratteri 'K' | ||
+ | for(j=0; j<n; j++) | ||
+ | { | ||
+ | int i; | ||
+ | char c = 'K'; | ||
+ | |||
+ | for(i=7; i>=0; i--) | ||
+ | { | ||
+ | if((c>>i)&1) // prendo l'i-esimo bit di c: | ||
+ | { // SIGUSR1 se e' 1 | ||
+ | if(kill(rx,SIGUSR1) == -1) | ||
+ | EXIT_WITH_ERROR("kill") | ||
+ | } | ||
+ | else // SIGUSR2 se invece e' 0 | ||
+ | { | ||
+ | if(kill(rx,SIGUSR2) == -1) | ||
+ | EXIT_WITH_ERROR("kill") | ||
+ | } | ||
+ | |||
+ | // sospendo il processo in attesa div SIGUSR1 | ||
+ | int len = read(sfd, &siginfo, sizeof(struct signalfd_siginfo)); | ||
+ | if(len != sizeof(struct signalfd_siginfo)) | ||
+ | EXIT_WITH_ERROR("read") | ||
+ | } | ||
+ | } | ||
+ | |||
+ | ftime(&time_end); | ||
+ | |||
+ | // calcolo il tempo medio di trasmissione | ||
+ | millisec = (time_end.time - time_start.time)*1000 + (time_end.millitm - time_start.millitm); | ||
+ | media = (float)(millisec)/n; | ||
+ | printf("Tempo medio: %f ms per carattere.\n",media); | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | <source lang="c"> | ||
+ | // Esercizio2: rxnull | ||
+ | |||
+ | #include <stdlib.h> | ||
+ | #include <stdio.h> | ||
+ | #include <string.h> | ||
+ | #include <signal.h> | ||
+ | #include <unistd.h> | ||
+ | #include <errno.h> | ||
+ | #include <sys/types.h> | ||
+ | #include <sys/signalfd.h> | ||
+ | |||
+ | #define EXIT_WITH_ERROR(function) \ | ||
+ | { \ | ||
+ | printf("Error %i in ",errno); \ | ||
+ | printf(function); \ | ||
+ | printf(": %s\n",strerror(errno)); \ | ||
+ | exit(EXIT_FAILURE); \ | ||
+ | } | ||
+ | |||
+ | int main(int argc, char *argv[]) | ||
+ | { | ||
+ | pid_t mypid; | ||
+ | sigset_t mask; | ||
+ | int sfd; | ||
+ | struct signalfd_siginfo siginfo; | ||
+ | char c; | ||
+ | |||
+ | mypid = getpid(); | ||
+ | printf("%i\n",mypid); | ||
+ | |||
+ | // setto il sigset_t | ||
+ | sigemptyset(&mask); | ||
+ | sigaddset(&mask, SIGUSR1); | ||
+ | sigaddset(&mask, SIGUSR2); | ||
+ | |||
+ | // annullo l'azione standard per SIGUSR1 e SIGUSR2 | ||
+ | if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) | ||
+ | EXIT_WITH_ERROR("sigprocmask") | ||
+ | |||
+ | sfd = signalfd(-1, &mask, 0); | ||
+ | if (sfd == -1) | ||
+ | EXIT_WITH_ERROR("signalfd") | ||
+ | |||
+ | do | ||
+ | { | ||
+ | int i; | ||
+ | c = 0; | ||
+ | |||
+ | for(i=7; i>=0; i--) | ||
+ | { | ||
+ | int len = read(sfd, &siginfo, sizeof(struct signalfd_siginfo)); | ||
+ | if(len != sizeof(struct signalfd_siginfo)) | ||
+ | EXIT_WITH_ERROR("read") | ||
+ | |||
+ | if (siginfo.ssi_signo == SIGUSR1) // se ho ricevuto SIGUSR1 | ||
+ | c = c | (1 << i); // setto il bit a 1 | ||
+ | // altrimenti e' sicuramente SIGUSR2 => il bit resta 0 | ||
+ | |||
+ | kill(siginfo.ssi_pid, SIGUSR1); // invio l'acknowledgement al mittente del segnale | ||
+ | } | ||
+ | } while(c != 0); // se tutti i bit a 0 => fine stringa | ||
+ | // NOTA: questo programma non termina normalmente se usato con txtime | ||
+ | |||
+ | printf("\n"); | ||
} | } | ||
</source> | </source> |
Latest revision as of 11:20, 30 June 2015
Esercizio1
Usando signalfd (e non signal o sigaction) scrivere due programmi tx e rx.
Rx deve essere attivato per primo e per prima cosa stampa il suo pid e aspetta.
Tx ha due parametri: il pid del ricevente rx e una stringa.
Rx deve stampare la stringa passata come secondo parametro e uscire. La stringa deve essere spedita usando solo segnali.
Ogni bit di ogni carattere deve essere inviato usando SIGUSR1 se vale 1 e SIGUSR2 se vale 0.
Al ricevimento di ogni bit rx spedisce un segnale di acknowledgement a tx che provvede a spedire il successivo
// Esercizio1: Tx
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/signalfd.h>
#define EXIT_WITH_ERROR(function) \
{ \
printf("Error %i in ",errno); \
printf(function); \
printf(": %s\n",strerror(errno)); \
exit(EXIT_FAILURE); \
}
int main(int argc, char *argv[])
{
pid_t rx;
char *str;
sigset_t mask;
int sfd;
struct signalfd_siginfo siginfo;
if(argc != 3)
{
printf("Usage: Tx rx string\n");
exit(1);
}
if(sscanf(argv[1],"%i",&rx) != 1)
EXIT_WITH_ERROR("sscanf");
str = argv[2];
// setto il sigset_t a contenere SIGUSR1 (sara' l'acknowledgement)
sigemptyset(&mask);
sigaddset(&mask, SIGUSR1);
// annullo l'azione standard per SIGUSR1
if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
EXIT_WITH_ERROR("sigprocmask")
sfd = signalfd(-1, &mask, 0);
if (sfd == -1)
EXIT_WITH_ERROR("signalfd");
while(1)
{
int i;
char c = *str;
// invia i bit del carattere (dal piu' al meno significativo)
for(i=7; i>=0; i--)
{
if((c>>i)&1) // prendo l'i-esimo bit di c:
{ // SIGUSR1 se e' 1
if(kill(rx,SIGUSR1) == -1)
EXIT_WITH_ERROR("kill")
}
else // SIGUSR2 se invece e' 0
{
if(kill(rx,SIGUSR2) == -1)
EXIT_WITH_ERROR("kill")
}
// attendo SIGUSR1 da Rx
int len = read(sfd, &siginfo, sizeof(struct signalfd_siginfo));
if(len != sizeof(struct signalfd_siginfo))
EXIT_WITH_ERROR("read")
}
if(c == 0) // esce se ha appena inviato fine-stringa
break;
str++;
}
return 0;
}
// Esercizio1: Rx
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/signalfd.h>
#define EXIT_WITH_ERROR(function) \
{ \
printf("Error %i in ",errno); \
printf(function); \
printf(": %s\n",strerror(errno)); \
exit(EXIT_FAILURE); \
}
int main(int argc, char *argv[])
{
pid_t mypid;
sigset_t mask;
int sfd;
struct signalfd_siginfo siginfo;
char c;
mypid = getpid();
printf("%i\n",mypid);
// setto il sigset_t
sigemptyset(&mask);
sigaddset(&mask, SIGUSR1);
sigaddset(&mask, SIGUSR2);
// annullo l'azione standard per SIGUSR1 e SIGUSR2
if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
EXIT_WITH_ERROR("sigprocmask")
sfd = signalfd(-1, &mask, 0);
if (sfd == -1)
EXIT_WITH_ERROR("signalfd")
do
{
int i;
c = 0;
// riceve 8 segnali per ogni carattere
for(i=7; i>=0; i--)
{
int len = read(sfd, &siginfo, sizeof(struct signalfd_siginfo));
if(len != sizeof(struct signalfd_siginfo))
EXIT_WITH_ERROR("read")
if (siginfo.ssi_signo == SIGUSR1) // se ho ricevuto SIGUSR1
c = c | (1 << i); // setto il bit a 1
// altrimenti e' sicuramente SIGUSR2 => il bit resta 0
kill(siginfo.ssi_pid, SIGUSR1); // invio l'acknowledgement al mittente del segnale
}
printf("%c",c);
} while(c != 0); // se tutti i bit a 0 => fine stringa
printf("\n");
return 0;
}
Esercizio2
Si costruiscano due programmi txtime e rxnull per stimare l'efficienza di tx e rx.
Rxnull e' uguale all'rx precedente ma non stampa nulla.
Txtime ha come parametri il pid del ricevente e un numero intero n. Txtime deve spedire n caratteri 'K' al txtnull e alla fine deve stampare
il tempo medio impiegato per spedire un carattere.
// Esercizio2: txtime
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/signalfd.h>
#include <sys/timeb.h>
#define EXIT_WITH_ERROR(function) \
{ \
printf("Error %i in ",errno); \
printf(function); \
printf(": %s\n",strerror(errno)); \
exit(EXIT_FAILURE); \
}
int main(int argc, char *argv[])
{
pid_t rx;
int n;
int j;
// variabili per calcolare il tempo medio di trasmissione
struct timeb time_start, time_end;
int millisec;
float media;
sigset_t mask;
int sfd;
struct signalfd_siginfo siginfo;
if(argc != 3)
{
printf("Usage: Tx rx string\n");
exit(1);
}
if(sscanf(argv[1],"%i",&rx) != 1)
EXIT_WITH_ERROR("sscanf");
if(sscanf(argv[2],"%i",&n) != 1)
EXIT_WITH_ERROR("sscanf");
ftime(&time_start);
// setto il sigset_t a contenere SIGUSR1 (sara' l'acknowledgement)
sigemptyset(&mask);
sigaddset(&mask, SIGUSR1);
// annullo l'azione standard per SIGUSR1
if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
EXIT_WITH_ERROR("sigprocmask")
sfd = signalfd(-1, &mask, 0);
if (sfd == -1)
EXIT_WITH_ERROR("signalfd");
// invio n caratteri 'K'
for(j=0; j<n; j++)
{
int i;
char c = 'K';
for(i=7; i>=0; i--)
{
if((c>>i)&1) // prendo l'i-esimo bit di c:
{ // SIGUSR1 se e' 1
if(kill(rx,SIGUSR1) == -1)
EXIT_WITH_ERROR("kill")
}
else // SIGUSR2 se invece e' 0
{
if(kill(rx,SIGUSR2) == -1)
EXIT_WITH_ERROR("kill")
}
// sospendo il processo in attesa div SIGUSR1
int len = read(sfd, &siginfo, sizeof(struct signalfd_siginfo));
if(len != sizeof(struct signalfd_siginfo))
EXIT_WITH_ERROR("read")
}
}
ftime(&time_end);
// calcolo il tempo medio di trasmissione
millisec = (time_end.time - time_start.time)*1000 + (time_end.millitm - time_start.millitm);
media = (float)(millisec)/n;
printf("Tempo medio: %f ms per carattere.\n",media);
}
// Esercizio2: rxnull
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/signalfd.h>
#define EXIT_WITH_ERROR(function) \
{ \
printf("Error %i in ",errno); \
printf(function); \
printf(": %s\n",strerror(errno)); \
exit(EXIT_FAILURE); \
}
int main(int argc, char *argv[])
{
pid_t mypid;
sigset_t mask;
int sfd;
struct signalfd_siginfo siginfo;
char c;
mypid = getpid();
printf("%i\n",mypid);
// setto il sigset_t
sigemptyset(&mask);
sigaddset(&mask, SIGUSR1);
sigaddset(&mask, SIGUSR2);
// annullo l'azione standard per SIGUSR1 e SIGUSR2
if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
EXIT_WITH_ERROR("sigprocmask")
sfd = signalfd(-1, &mask, 0);
if (sfd == -1)
EXIT_WITH_ERROR("signalfd")
do
{
int i;
c = 0;
for(i=7; i>=0; i--)
{
int len = read(sfd, &siginfo, sizeof(struct signalfd_siginfo));
if(len != sizeof(struct signalfd_siginfo))
EXIT_WITH_ERROR("read")
if (siginfo.ssi_signo == SIGUSR1) // se ho ricevuto SIGUSR1
c = c | (1 << i); // setto il bit a 1
// altrimenti e' sicuramente SIGUSR2 => il bit resta 0
kill(siginfo.ssi_pid, SIGUSR1); // invio l'acknowledgement al mittente del segnale
}
} while(c != 0); // se tutti i bit a 0 => fine stringa
// NOTA: questo programma non termina normalmente se usato con txtime
printf("\n");
}