Pasar al contenido principal

Práctica 5

Versión para impresiónSend by email

Esta práctica es muy parecida a la práctica 4, el principal cambio es que se redirige la salida o entrada estándar de cada uno de los procesos y se ejecutan programas externos (awk y sort) para que sus salidas y entradas interaccionen entre sí.

 


pipeline.c - Se crean dos procesos con una tubería. Uno de ellos llama a awk y se lo pasa por la tubería al segundo, que ejecuta sort

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


/**
 * productor
 *
 * Ejecuta el programa awk -F {print $5} /etc/passwd
 */
void productor(void) {							
  execlp("awk", "awk", "-F:", "{print $5}", "/etc/passwd", NULL);
  perror("execlp");
  exit(1);
}

/**
 * consumidor
 *
 * Ejecuta el programa sort
 */
void consumidor(void) {
  execlp("sort", "sort", NULL);
  perror("execlp");
  exit(1);
}

/**
 * main
 *
 * Llama a dos procesos y redirige la salida del primero a 
 * la entrada del segundo
 */
int main(void) {
  int pid;
  int tubo[2];

  pipe(tubo);						// creamos el pipe
  if ((pid= fork())==0) {				// fork - Proceso Hijo
    close(tubo[0]);					// cerramos la entrada del tubo 0
	// dup2 duplica un file descriptor, util para redirigir la salida (automaticamente cierra la vieja)
	// Recuerda: STDIN = 0, STDOUT = 1, STERR = 2
    dup2(tubo[1], 1);					// Duplica la salida del tubo y se la asigna a la salida estandar
    close(tubo[1]);					// Cierra la salida del tubo
    productor();					// y ejecuta productor
  }
  else {						// Proceso Padre
    close(tubo[1]);					// cierra la salida del tubo
    dup2(tubo[0], 0);					// Duplica la entrada del tubo y se la asigna a la entrada estandar
    close(tubo[0]);					// Cierra la entrada del tubo
    consumidor();					// y ejecuta consumidor
  }

/*
 La idea de esto es:

   productor - STOUT -> salida tubo

   entrada tubo -> STDIN - consumidor
 
 awk - Procesa texto estructurado en campos. En este caso, extrae el 5o campo del archivo
       separado por ':' de /etc/passwd (Verlo para mayor detalle)
 sort - Ordena lineas

*/
}				        				        					 

 Ejecución:
 

merlin1@merlins1:~/Escritorio/Practicas/5$ gcc pipeline.c -o pipeline
merlin1@merlins1:~/Escritorio/Practicas/5$ ./pipeline

Avahi autoip daemon,,,
Avahi mDNS daemon,,,
backup
bin
CouchDB Administrator,,,
daemon
games
Gnats Bug-Reporting System (admin)
Gnome Display Manager
Hardware abstraction layer,,,
HPLIP system user,,,
ircd
Kernel Oops Tracking Daemon,,,
lp
mail
Mailing List Manager
man
merlin1,-,-,-,-
Merlitec,,,
MySQL Server,,,
news
nobody
proxy
PulseAudio daemon,,,
RealtimeKit,,,
root
Speech Dispatcher,,,
sync
sys
TiMidity++ MIDI sequencer service
usbmux daemon,,,
uucp
Vero,,,,
www-data
merlin1@merlins1:~/Escritorio/Practicas/5$

 

Resultados Pedidos:

Explicación del funcionamiento:

Explicado en el propio código

 

Modificación para que ordene en orden alfabético inverso:

pipeline2.c - Se crean dos procesos con una tubería. Uno de ellos llama a awk y se lo pasa por la tubería al segundo, que ejecuta sort. El sort se llama con la opción -r para que lo ordene por orden alfabético inverso

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


/**
 * productor
 *
 * Ejecuta el programa awk -F {print $5} /etc/passwd
 */
void productor(void) {							
  execlp("awk", "awk", "-F:", "{print $5}", "/etc/passwd", NULL);
  perror("execlp");
  exit(1);
}

/**
 * consumidor
 *
 * Ejecuta el programa sort -r
 */
void consumidor(void) {
  execlp("sort", "sort", "-r", NULL);
  perror("execlp");
  exit(1);
}

/**
 * main
 *
 * Llama a dos procesos y redirige la salida del primero a 
 * la entrada del segundo
 */
int main(void) {
  int pid;
  int tubo[2];

  pipe(tubo);						// creamos el pipe
  if ((pid= fork())==0) {				// fork - Proceso Hijo
    close(tubo[0]);					// cerramos la entrada del tubo 0
	// dup2 duplica un file descriptor, util para redirigir salida (automaticamente cierra la vieja)
	// Recuerda: STDIN = 0, STDOUT = 1, STERR = 2
    dup2(tubo[1], 1);					// Duplica la salida del tubo y se la asigna a la salida estandar
    close(tubo[1]);					// Cierra la salida del tubo
    productor();					// y ejecuta productor
  }
  else {						// Proceso Padre
    close(tubo[1]);					// cierra la salida del tubo
    dup2(tubo[0], 0);					// Duplica la entrada del tubo y se la asigna a la entrada estandar
    close(tubo[0]);					// Cierra la entrada del tubo
    consumidor();					// y ejecuta consumidor
  }

/*
 La idea de esto es:

   productor - STOUT -> salida tubo

   entrada tubo -> STDIN - consumidor
 
 awk - Procesa texto estructurado en campos. En este caso, extrae el 5o campo del archivo
       separado por ':' de /etc/passwd (Verlo para mayor detalle)
 sort - Ordena lineas

*/
}

 

 Ejecución:
 

merlin1@merlins1:~/Escritorio/Practicas/5$ gcc pipeline2.c -o pipeline2
merlin1@merlins1:~/Escritorio/Practicas/5$ ./pipeline2
www-data
Vero,,,,
uucp
usbmux daemon,,,
TiMidity++ MIDI sequencer service
sys
sync
Speech Dispatcher,,,
root
RealtimeKit,,,
PulseAudio daemon,,,
proxy
nobody
news
MySQL Server,,,
Merlitec,,,
merlin1,-,-,-,-
man
Mailing List Manager
mail
lp
Kernel Oops Tracking Daemon,,,
ircd
HPLIP system user,,,
Hardware abstraction layer,,,
Gnome Display Manager
Gnats Bug-Reporting System (admin)
games
daemon
CouchDB Administrator,,,
bin
backup
Avahi mDNS daemon,,,
Avahi autoip daemon,,,

merlin1@merlins1:~/Escritorio/Practicas/5$

 

AdjuntoTamaño
pipeline2.c1.56 KB