Unitat 3 · Sistemes Operatius (SO)
Les pipes es poden implementar com a buffers circulars basats en memòria assignada pel sistema operatiu. Aquestes pipes es coneixen com a pipes sense nom i són transitòries. Una pipe sense nom deixa d’existir quan tots els processos que la tenen assiganda acaben o tanquen els seus descriptors associats a la pipe.

Els pipes es creen en el moment que s’obren mitjançant la crida a sistema pipe() (unistd.h) o amb la sintaxis |.
pipe(), crea dos descriptors de fitxer. Un de lectura (desc[0]) i un d’escriptura (desc[1]).pipe() s’ha creat; per poder utilitzar-lo els processos han d’heretar aquests descriptors del procés pare.


void main(){
int fd[2]; // Descriptors associats a una pipe
pid_t pidFill;
/* El primer element de la matriu (fd[0]) està configurat i obert per
a la lectura, mentre que el segon element està configurat i obert per
escriure (fd[1]. Totes les dades que viatgen per la pipe es mouen
pel nucli. */
pipe(fd); pidFill = fork();
if (pidFill == -1){
perror("fork"); exit(1);
} else if (pidFill == 0){
/*El procés fill tanca la escriptura per la pipe*/ close(fd[1]);
} else {
/* El procés pare tanca la lectura per la pipe */ close(fd[0]);
}
}fork() creant una còpia del pare i duplicant els descriptors de fitxers associats a les dues pipes.

Per utilitzar pipes amb la crida a sistema exec i simular el comportament del sistema operatiu quan interactuem amb la shell, necessitem redireccionar la sortida i l’entrada de la pipe a descriptors de fitxers predefinits assignats a cada procés.

dup()(unistd.h).dup() i dup2()ls | wc -l (I)ls | wc -l (II)ls no escriurà per stdout i ho farà per la pipe. D’aquesta manera no veurem el llista de fitxers a la terminal, seran enviats a la pipe.ls.wc -l escriu a stdout, com ara no hi ha cap més pipe. Aquesta sortida no es redirecciona i per tant únicament veurem el resultat per stdout. És a dir, el nombre de fitxers i directoris del directori actual.ls | wc -l (III)ls | wc -lint main(int argc, char *argv[]){
int fd[2];
char *p1[] = {"ls", NULL};
char *p2[] = {"wc", "-l", NULL};
if (pipe(fd)<0){ perror("Error de creació del pipe fd[]");exit(-1);}
int pid1;int pid2;
switch (pid1 = fork()){
case -1: perror("Error fork()"); exit(-2); break;
case 0: //@TODO
}
switch (pid2 = fork()){
case -1: perror("Error fork()"); exit(-2); break;
case 0: //@TODO
}
waitpid(pid1,0,0);
waitpid(pid2,0,0);
}ls | wc -lls)if (close(pfd[0]) == -1)
perror("close 1");
/* Duplicate stdout on write end of pipe;
close duplicated descriptor */
if (fd[1] != STDOUT_FILENO) {
if (dup2(fd[1], STDOUT_FILENO) == -1)
perror("dup2 1");
if (close(fd[1]) == -1)
perror("close 2");
}
execlp("ls", "ls", (char *) NULL);
perror("execlp ls");ls | wc -lwc -l) if (close(fd[1]) == -1)
perror("close 3");
/* Duplicate stdin on read end of pipe;
close duplicated descriptor */
if (fd[0] != STDIN_FILENO) {
if (dup2(fd[0], STDIN_FILENO) == -1)
perror("dup2 2");
if (close(fd[0]) == -1)
perror("close 4");
}
execlp("wc", "wc", "-l", (char *) NULL);
perror("execlp wc");ls | wc -lCom és que el programa no acaba mai?
El procés pare ha de tancar els descriptors de fitxer que no utilitza. Si no els procés fill lector de la pipe no acaba mai. Ja que no tots els processos han tancat els descriptors de fitxer associats a la pipe.
Les pipes són mecanismes de comunicació entre processos que permeten la transmissió de dades d’un procés a un altre. Es poden utilitzar per a comunicació unidireccional o bidireccional. Cal comprendre com crear pipes, escriure i llegir dades en elles, i com utilitzar-les en la redirecció d’entrada/sortida de processos en execució.


Unitat 3 · Sistemes Operatius (SO) 🏠