Warning: Undefined array key "view" in /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php on line 2
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php:2) in /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php on line 47
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php:2) in /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php on line 48
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php:2) in /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php on line 49
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php:2) in /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php on line 50
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php:2) in /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php on line 51
/* Sistemi Operativi - prova di laboratorio
compito del 23/07/2015 - soluzione */
#include
#include
#include
#include
#include
#include
#include
#include
#define ALPHABET_SIZE 26
/* la struttura di un messaggio scambiato tra i processi: */
typedef struct {
long type; // 1: messaggi ordinari, 2: errore
unsigned long occurrences[ALPHABET_SIZE]; // il numero di occorrenze trovate per ogni lettera
} msg;
/* il generico figlio T-n che legge e analizza il file-n */
void child(int num, char *file, int queue) {
msg message;
struct stat statbuf;
int fd;
long i;
char *map;
/* prepara il messaggio da inviare e azzera le occorrenze */
message.type = 1;
for (i = 0; i < ALPHABET_SIZE; i++)
message.occurrences[i] = 0;
/* apre il file e lo mappa in memoria */
if (stat(file, &statbuf) || !S_ISREG(statbuf.st_mode)) {
message.type = 2;
msgsnd(queue, &message, sizeof(message) - sizeof(long), 0);
exit(1);
}
if (((fd = open(file, O_RDONLY)) == -1) || ((map = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED)) {
message.type = 2;
msgsnd(queue, &message, sizeof(message) - sizeof(long), 0);
exit(2);
}
/* calcola le occorrenze delle sole lettere */
for (i = 0; i < statbuf.st_size; i++)
if ((map[i] >= 'a') && (map[i] <= 'z'))
message.occurrences[map[i] - 'a']++;
else if ((map[i] >= 'A') && (map[i] <= 'Z'))
message.occurrences[map[i] - 'A']++;
printf("processo T-%d su file '%s':\n ", num, file);
for (i = 0; i < ALPHABET_SIZE; i++)
printf("%c:%ld ", 'a' + i, message.occurrences[i]);
printf("\n");
/* invia il messaggio con i dati raccolti */
if (msgsnd(queue, &message, sizeof(message) - sizeof(long), 0) == -1)
perror("msgsnd");
exit(0);
}
int main(int argc, char **argv) {
int queue;
int children, i, j, max, exaequo;
msg message;
unsigned long total_occ[ALPHABET_SIZE];
if (argc <= 1) {
fprintf(stderr, "uso: %s ...\n", argv[0]);
exit(1);
}
if ((queue = msgget(IPC_PRIVATE, IPC_CREAT|0600)) == -1) {
perror("msgget");
exit(1);
}
/* crea i processi figli necessari */
for (i = 1; i < argc; i++)
if (fork() == 0)
child(i, argv[i], queue);
children = argc-1;
/* azzera i totali */
for (i = 0; i < ALPHABET_SIZE; i++)
total_occ[i] = 0;
/* attende tanti messaggi quanti sono i figli */
for (i = 0; i < children; i++) {
if (msgrcv(queue, &message, sizeof(message) - sizeof(long), 0, 0) == -1)
perror("msgrcv");
if (message.type == 2) {
printf("errore dal figlio!\n");
continue;
}
/* aggrega i dati del messaggio ai totali */
for (j = 0; j < ALPHABET_SIZE; j++)
total_occ[j] += message.occurrences[j];
}
/* visualizza i totali e controlla se c'è un massimo assoluto */
printf("processo padre P:\n ");
max = 0; exaequo = 0;
for (i = 0; i < ALPHABET_SIZE; i++) {
printf("%c:%ld ", 'a' + i, total_occ[i]);
if (total_occ[i] == total_occ[max])
exaequo = 1;
else if (total_occ[i] > total_occ[max]) {
max = i;
exaequo = 0;
}
}
printf("\n");
if (!exaequo)
printf(" lettera più utilizzata: '%c'\n", 'a' + max);
/* rimuove la coda persistente */
msgctl(queue, IPC_RMID, NULL);
}