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