Sei sulla pagina 1di 9

Ricerca TPS

Funzione Wait():
La funzione wait() viene utilizzata per far sì che un processo genitore attenda che uno dei propri
processi figli termini l'esecuzione. Questa funzione è utilizzata in ambienti di programmazione
concorrente o in sistemi operativi multitasking.

Ecco una spiegazione dettagliata del funzionamento della funzione wait():

1. Dopo aver creato uno o più processi figli, il processo genitore può utilizzare la funzione wait()
per bloccarsi e attendere la terminazione di uno qualsiasi dei propri processi figli.

2. Quando un processo figlio termina, il processo genitore viene sbloccato dalla chiamata a wait()
e può continuare l'esecuzione. La funzione wait() restituisce il PID (Process ID) del processo figlio
che ha terminato, consentendo al processo genitore di identificare quale dei suoi processi figli ha
completato l'esecuzione.

3. Dopo che il processo figlio termina, il processo genitore può utilizzare altre funzioni (come
WEXITSTATUS() o WIFEXITED()) per determinare lo stato di uscita del processo figlio e altre
informazioni pertinenti sulla sua terminazione.

4. Dopo aver ricevuto il PID del processo figlio terminato da wait(), il processo genitore può
eseguire qualsiasi altra azione necessaria nel proprio codice. Ad esempio, potrebbe decidere se
creare ulteriori processi figli o terminare l'esecuzione.

Esempio di utilizzo:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
pid_t pid_figlio; // pid del processo figlio

// Creazione del processo figlio


pid_figlio = fork();

if (pid_figlio == 0) {
// Processo figlio
printf("Sono il processo figlio con PID %d\n", getpid());
sleep(5); // Il processo figlio dorme per 5 secondi
printf("Il processo figlio sta per terminare\n");
exit(0);
} else if (pid_figlio > 0) {
// Processo padre
printf("Sono il processo padre con PID %d\n", getpid());
printf("In attesa della terminazione del processo figlio...\n");

// Il processo padre attende la terminazione del processo figlio


wait(NULL);
printf("Il processo figlio è terminato\n");
} else {
// Errore nella creazione del processo
perror("Errore nella creazione del processo figlio");
exit(1);
}

return 0;
}
Funzione Waitpid();
La funzione waitpid() in C è utilizzata per far sì che un processo genitore attenda la terminazione
di un processo figlio specifico o di uno qualsiasi dei suoi processi figli, a seconda dei parametri
specificati. Firma della funzione:
pid_t waitpid(pid_t pid, int *status, int options);

La funzione waitpid() ritorna il PID del processo figlio che ha terminato l'esecuzione, -1 se si
verifica un errore o 0 se è specificato l'opzione WNOHANG e non ci sono processi figli terminati.

Esempio di utilizzo con annessi controlli di funzionamento:


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main() {
pid_t pid_figlio; // pid del processo figlio
int status; // stato di terminazione del processo figlio

// Creazione del processo figlio


pid_figlio = fork();

if (pid_figlio == 0) {
// Processo figlio
printf("Sono il processo figlio con PID %d\n", getpid());
sleep(5); // Il processo figlio dorme per 5 secondi
printf("Il processo figlio sta per terminare\n");
exit(1); // Il processo figlio termina con un codice di ritorno di 1
} else if (pid_figlio > 0) {
// Processo padre
printf("Sono il processo padre con PID %d\n", getpid());
printf("In attesa della terminazione del processo figlio...\n");

// Il processo padre attende la terminazione del processo figlio


// e controlla lo stato di terminazione
waitpid(pid_figlio, &status, 0);

if (WIFEXITED(status)) {
printf("Il processo figlio è terminato con codice di ritorno %d\n", WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
printf("Il processo figlio è stato terminato da un segnale con numero %d\n", WTERMSIG(status));
}
} else {
// Errore nella creazione del processo
perror("Errore nella creazione del processo figlio");
exit(1);
}
return 0;
}
Funzione Pipe();

La funzione pipe() in C viene utilizzata per creare una pipe, ovvero un meccanismo di
comunicazione tra due processi, in cui un processo scrive dati nella pipe e l'altro processo legge
questi dati dalla pipe. È unidirezionale, il che significa che i dati fluiscono in un'unica direzione.

Ecco la firma della funzione pipe():


int pipe(int pipefd[2]);

Dove pipefd è un array di interi di lunghezza 2, dove pipefd[0] è il file descriptor per la lettura
dalla pipe e pipefd[1] è il file descriptor per la scrittura nella pipe.

La funzione pipe() crea una nuova pipe e restituisce 0 in caso di successo e -1 in caso di errore. Gli
errori possono essere dovuti a diverse ragioni, ad esempio, se non c'è sufficiente spazio di
memoria disponibile per creare la pipe o se si supera il limite massimo di file descriptor aperti.

Esempio di utilizzo con annessi controlli di funzionamento:


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
int fd[2]; // Array di due file descriptor
pid_t pid_figlio; // pid del processo figlio

// Creazione della pipe


if (pipe(fd) == -1) {
perror("Errore nella creazione della pipe");
exit(1);
}

// Creazione del processo figlio


pid_figlio = fork();

if (pid_figlio == 0) {
// Processo figlio
char messaggio[] = "Ciao dal processo figlio!";

// Chiusura del descrittore di lettura della pipe nel processo figlio


close(fd[0]);

// Scrittura sul descrittore di scrittura della pipe


write(fd[1], messaggio, sizeof(messaggio));

// Chiusura del descrittore di scrittura della pipe nel processo figlio


close(fd[1]);
exit(0);
} else if (pid_figlio > 0) {
// Processo padre
char buffer[100];

// Chiusura del descrittore di scrittura della pipe nel processo padre


close(fd[1]);

// Lettura dal descrittore di lettura della pipe


read(fd[0], buffer, sizeof(buffer));

// Stampa del messaggio ricevuto dal processo figlio


printf("Messaggio ricevuto dal processo figlio: %s\n", buffer);

// Chiusura del descrittore di lettura della pipe nel processo padre


close(fd[0]);
} else {
// Errore nella creazione del processo
perror("Errore nella creazione del processo figlio");
exit(1);
}

return 0;
}
Programma Matrice:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <mtwister.h>

// Funzione per generare una matrice di numeri random


void generaMatrice(int matrice, int n, int m) {
// Inizializzazione generatore
mtwister_init();

for (int i = 0; i < n; i++) {


for (int j = 0; j < m; j++) {
// Generazione numero casuale con distribuzione uniforme
matrice[i m + j] = mtwister_rand() % 100;
}
}
}

// Funzione per la somma delle righe di una matrice


int sommaRiga(int matrice, int n, int m, int riga) {
int somma = 0;
for (int i = 0; i < m; i++) {
somma += matrice[riga m + i];
}
return somma;
}

int main() {
int n, m;

// Acquisizione dimensioni matrice


printf("Inserisci il numero di righe: ");
scanf("%d", &n);
printf("Inserisci il numero di colonne: ");
scanf("%d", &m);

// Allocazione memoria matrice


int matrice = (int)malloc(n * m * sizeof(int));

// Creazione pipe
int pipefd[2];
if (pipe(pipefd) == -1) {
perror("Errore creazione pipe");
exit(1);
}

// Creazione figli
for (int i = 0; i < n; i++) {
pid_t pid = fork();
if (pid == -1) {
perror("Errore creazione figlio");
exit(1);
}

if (pid == 0) { // Figlio
// Chiusura lato di scrittura della pipe
close(pipefd[1]);

// Calcolo somma riga


int sommaRiga = sommaRiga(matrice, n, m, i);

// Invio somma al padre


write(pipefd[0], &sommaRiga, sizeof(int));

// Chiusura lato di lettura della pipe


close(pipefd[0]);

exit(0);
}
}

// Chiusura lato di lettura della pipe


close(pipefd[0]);
// Somma totale
int sommaTotale = 0;
int sommaFiglio;
for (int i = 0; i < n; i++) {
// Lettura somma dal figlio
read(pipefd[1], &sommaFiglio, sizeof(int));

// Aggiornamento somma totale


sommaTotale += sommaFiglio;
}

// Chiusura lato di scrittura della pipe


close(pipefd[1]);

// Stampa risultato
printf("Somma totale: %d\n", sommaTotale);

// Attesa figli
for (int i = 0; i < n; i++) {
wait(NULL);
}

return 0;
}

Potrebbero piacerti anche