PDA

Visualizza la versione completa : [c] pipe


Pierissimo
25-11-2008, 17:03
ragazzi sto studiando sistemi distribuiti, le pipe precisamente, e mi sono ritrovato davanti questo pezzo di codice, che dovrebbe esegure in una shell linux il comando "ls | sort". ecco il codice non l ho capito per niente! help!


#include <sys/types.h>
#include <unistd.h>
pid_t pid;
int pipefd[2];
int main()
{
pipe(pipefd);
if ((pid = fork()) == (pid_t)0) { // processo figlio
close(1); // close stdout (assumed open)
dup(pipefd[1]); // dups arg to min free descriptor
close(pipefd[0]);
execlp("ls", "ls", "-1t", (char *)0);
} else if (pid > (pid_t)0) { // processo padre
close(0); // close stdin (assumed open)
dup(pipefd[0]);
close(pipefd[1]);
execlp("sort", "sort", "-r", (char *)0);
}
return(0);
}

MItaly
25-11-2008, 17:13
La parte del fork e dell'exec l'hai capita? Il problema è solo la pipe?

Pierissimo
25-11-2008, 17:17
sinceramente no..
perchè c'è la necessità di fare una fork()?
perchè controlliamo se il pid della fork è 0?inoltre perchè fare il casting a pid_t di 0?
scusami sono un pò confuso!

MItaly
25-11-2008, 17:54
Originariamente inviato da Pierissimo
perchè c'è la necessità di fare una fork()?

Perché quel codice lancia ls e prepara il recupero di quello che esso scrive su stdout tramite la pipe; in effetti quel codice è incompleto, manca la parte di recupero del testo scritto da ls.


perchè controlliamo se il pid della fork è 0?
Perché se la fork restituisce 0 vuol dire che siamo nel processo figlio, se restituisce un altro valore siamo nel processo padre. Queste sono le basi della creazione dei processi sotto sistemi Unix-like, le hai mai studiate?


inoltre perchè fare il casting a pid_t di 0?

Per coerenza con il tipo di pid.

Pierissimo
25-11-2008, 18:01
quindi in pratica, il 1 processo esegue quello che c'è nel primo if, la fork esegue quello che c'è nel secondo if... giusto?

MItaly
25-11-2008, 18:13
Esattamente; la fork crea un nuovo processo che è un clone esatto di quello corrente, e nel processo nuovo restituisce 0, mentre nel processo vecchio restituisce il PID del processo nuovo. Il processo nuovo in questo caso chiude il descrittore file di stdout (close(1)) e collega stdout ad un'estremità della pipe (dup(pipefd[1]); questa riga funziona perché dup duplica il descrittore file passatogli, assegnando al nuovo descrittore l'ID più basso disponibile, che in questo caso è 1, che è quello che corrisponde a stdout). Quindi chiude il descrittore corrispondente all'altra estremità della pipe e chiama la exec, che rimpiazza completamente il "contenuto" del processo corrente con ls; il processo però mantiene diversi attributi precedenti all'exec, tra cui i descrittori file, per cui ls, scrivendo su stdout, andrà in realtà a scrivere sull'estremità della pipe che è stata duplicata prima.
Il processo vecchio, invece, collega l'altra estremità della pipe a stdin (chiudendo il descrittore 2 e duplicando l'altra estremità della pipe in maniera analoga a quanto fatto dal processo figlio).

Pierissimo
25-11-2008, 18:22
adesso è molto più chiaro!
grazie mille!

MItaly
25-11-2008, 18:25
Di niente, ciao! :ciauz:

Loading