Title: Amelia Guill
1Linux Pipe
- Amelia Guillén Rodríguez
- Michael Kokaly Kokaly
2PIPE INTRODUCCION
- Transmisión de datos entre procesos a través de
un canal datos escritos en un extremo se leen
en el otro extremo. - Podemos comparar tuberías con una cola FIFO de
caracteres.
3PIPEINTRODUCCION
- Las tuberías no ofrecen comunicación
estructurada. - Desventaja lectura de datos independiente de la
escritura. - Ventaja permite leer de una sola vez los datos
escritos en varias ocasiones. - La gestión de las tuberías esta integrada en el
sistema de archivos. - Acceso a las tuberías por descriptores de
entrada/salida uno para lectura en la tubería y
otro para la escritura en la tubería
4TUBERIAS TIPOS
- Tubería anónima
- Creada por un proceso.
- Transmisión de descriptores sólo por herencia
hacia sus descendientes. - Mecanismo restrictivo sólo comunicación entre
procesos cuyo antecesor común es el creador de la
tubería.
5TUBERIAS TIPOS
- Tubería con nombre
- Existen físicamente en el sistema de archivos.
- Se manipulan como archivos respecto a
operaciones de apertura,cierre,lectura y
escritura,por lo que no existe la restricción de
las anónimas. - Para identificar un archivo tipo tubería con
nombre utilizamos el atributo p del comando ls.
6TUBERIAS ANONIMAS.CREACION
- Llamada pipe para crear una tubería anónima.
- Para poder crearla se pasan como parámetro una
tabla de dos enteros - include ltunistd.hgt
- int pipe (int filedes2)
- Si la llamada ha sido exitosa filedes0
contendrá el descriptor de lectura y filedes1
contendrá el descriptor de escritura. -
7TUBERIAS ANONIMAS CREACION ERRORES
- La llamada pipe puede generar errores
- EFAULT La tabla pasada como parámetro no es
válida. - EMFILE Se ha alcanzado el número máximo de
archivos abiertos para el proceso actual. - ENFILE Se ha alcanzado el número máximo de
archivos abiertos en el sistema
8TUBERIAS ANONIMAS
- Se pueden utilizar funciones de alto nivel para
operaciones de lectura y escritura
printf,scanf,sprintf - Problemas todo carácter escrito no está
disponible en el otro extremo de inmediato ya que
usan memorias intermedias.
9TUBERIAS ANONIMAS
- La llamada al sistema close permite cerrar
descriptores inutilizados. - El proceso lector queda bloqueado hasta que lee
la cantidad de datos precisa en la llamada read.
10TUBERIA ANONIMACREACION TUBERIA-EJECUCION
PROGRAMA
- Una tubería puede emplearse para comunicarse con
un programa externo. - Para ello dos funciones de biblioteca
-
- include ltstdio.hgt
- FILE popen (const char command, const
char type) - int pclose (FILE stream)
- Popen crea una tubería y un proceso hijo.
- El proceso hijo ejecuta el comando especificado
por command. - Pclose cierra la tuberia (fclose) y finaliza el
proceso hijo asociado
11TUBERIA ANONIMACREACION TUBERIA-EJECUCION
PROGRAMA
- Popen devuelve un descriptor de entradas/salidas
correspondiente a la tubería, según el valor de
parámetro type - Si type es la cadena ltltrgtgt, el descriptor es
accesible en lectura, y permite acceder a la
salida estándar del mandato. - Si type es la cadena ltltwgtgt, el descriptor es
accesible en escritura, y permite acceder a la
entrada estándar del mandato.
12IMPLEMENTACION
- Desde el punto de vista de i-nodo de una tubería,
el campo i_pipe se pone a 1, lo que identifica el
tipo de i-nodo. - El campo u del i-nodo está constituido, en el
caso de una tubería (anónima o no), por la
estructura pipe_inode_info descrita en el archivo
ltlinux/pipe_fs_i.hgt. - El tamaño de la tubería se limita a 4 KB (valor
de la constante PIPE_BUF definida en el archivo
ltlinux/limits.hgt). - Este límite corresponde al valor límite para la
realización de una escritura atómica en la
tubería. El usuario puede escribir más datos en
la tubería, pero dejará de tener garantizada la
atomización de la operación.
13PIPE_INODE_INFO
Tipo Campo Descripción
Struct wait_queue Wait Sincroniza los accesos concurrentes a la tubería
Char Base Puntero a la página de memoria destinada a los datos
Unsigned int Start Posición en la página de memoria
Unsigned int Len Número de bytes es espera en la tubería
Unsigned int Lock Bloqueo sobre la tubería
Unsigned int Rd_openers Número de procesos que han abierto la tubería con nombre en lectura
Unsigned int Wr_openers Número de procesos que han abierto la tubería con nombre en escritura
Unsigned int Readers Número de procesos que tienen acceso en lectura a la tubería
Unsigned int writers Número de procesos que tienen acceso en escritura a la tubería
14DO_PIPE
- int do_pipe(int fd)
-
- struct inode inode
- struct file f1, f2
- int error
-
- error -ENFILE
- f1 get_empty_filp()
- if (!f1)
- goto no_files
- f2 get_empty_filp()
- if (!f2)
- goto close_f1
- inode get_pipe_inode() //creación del i-nodo
de 1 tubería - if (!inode)
- goto close_f12
- error get_unused_fd()
15DO_PIPE
- if (error lt 0)
- goto close_f12_inode
- i error
- error get_unused_fd()
- if (error lt 0)
- goto close_f12_inode_i
- j error
- Error -ENOMEM
- sprintf(name, "lu", inode-gti_ino)//Escribe el
número
-
que caracteriza el inode - this.name name
-
- dentry d_alloc(pipe_mnt-gtmnt_sb-gts_root,
this) - if (!dentry)
- .
- d_add(dentry, inode) //Añade el inode al
directorio dentry -
16GET_PIPE_INODE(fs/pipe.c)
- static struct inode get_pipe_inode(void)
- //crea el inodo
- struct inode inode new_inode(pipe_mnt-gtmnt_sb)
- if (!inode)
- goto fail_inode
- if(!pipe_new(inode)) //asigna una pagina de
memoria para contener los datos - goto fail_iput
- //inicializaciones
- PIPE_READERS(inode) PIPE_WRITERS(inode) 1
- inode-gti_fop rdwr_pipe_fops //operaciones
17GET_PIPE_INODE(fs/pipe.c)
- inode-gti_state I_DIRTY
- inode-gti_mode S_IFIFO S_IRUSR S_IWUSR
- inode-gti_uid current-gtfsuid
- inode-gti_gid current-gtfsgid
- inode-gti_atime inode-gti_mtime inode-gti_ctime
CURRENT_TIME - inode-gti_blksize PAGE_SIZE
- return inode
18GET_PIPE_INODE(fs/pipe.c)
- fail_iput
- iput(inode)
- fail_inode
- return NULL
-
19PIPE_NEW(fs/pipe.c)
- struct inode pipe_new(struct inode inode)
-
- unsigned long page
- page __get_free_page(GFP_USER)//asigna 1
pagina de memoria para contener los datos - if (!page)
- return NULL
- inode-gti_pipe kmalloc(sizeof(struct
pipe_inode_info), GFP_KERNEL)//Crea la
estructura pipe_inode_info - if (!inode-gti_pipe)
- goto fail_page
20PIPE_NEW(fs/pipe.c)
- init_waitqueue_head(PIPE_WAIT(inode))
- PIPE_BASE(inode) (char) page
- PIPE_START(inode) PIPE_LEN(inode) 0
- PIPE_READERS(inode) PIPE_WRITERS(inode) 0
- PIPE_WAITING_READERS(inode)
- PIPE_WAITING_WRITERS(inode) 0
- PIPE_RCOUNTER(inode) PIPE_WCOUNTER(inode)
1 - return inode
- fail_page
- free_page(page)
- return NULL
-
21TUBERIAS CON NOMBRECREACION
- Prototipo función mkfifo
- include ltsys/stat.hgt
- int mkfifo (const char path, mode_t mode)
- Esta función se implementa con la llamada mknod.
- mknod (path, mode S_IFIFO, 0)
- Las tuberías con nombre permiten e/s con bloqueo
o sin bloqueo. - Para no bloqueo especificar opción O_NODELAY o
O_NONBLOCK al abrir con open. - Salvo lseek todas las operaciones de manipulación
de un archivo son válidas.
22IMPLEMENTACION TUBERIAS CON NOMBRE
- La creación de una tubería con nombre corresponde
a la creación de un archivo cualquiera, y se
detalla en el archivo fs/fifo.c. - Las operaciones de lectura y de escritura se
encuentran en el archivo destinado a las tuberías
anónimas fs/pipe.c.
23IMPLEMENTACION Creación tubería con nombre
- La creación de una tubería con nombre se efectúa
por la función fifo-open, definida en el archivo
fuente fs/fifo.c. Esta función se llama mediante
la función de inicialización de una tubería con
nombre init_fifo. - La creación de una nueva tubería con nombre
depende de las opciones de la creación. Las
operaciones autorizadas sobre el i-nodo se fijan
en función de estas opciones. - Lectura exclusiva connecting_fifo_fops en el
caso de una lectura sin bloqueo, read_fifo_fops
en caso contrario - Escritura exclusiva write_fifo_fops
- Lectura y escritura rdwr_fifo_fops
24FIFO_OPEN(fs/fifo.c)
- Static int fifo_open(struct inode inode, struct
file filp) -
- int ret
- ret -ERESTARTSYS
- lock_kernel()
- if (down_interruptible(PIPE_SEM(inode)))
- goto err_nolock_nocleanup
-
- if (!inode-gti_pipe)
- ret -ENOMEM
- if(!pipe_new(inode))
- goto err_nocleanup
-
-
25FIFO_OPEN(fs/fifo.c)
- switch (filp-gtf_mode)
- case 1 //solo lectura
- filp-gtf_op read_fifo_fops
- PIPE_RCOUNTER(inode)
- PIPE_READERS(inode)
- ...
- case 2 //solo escritura
- ret -ENXIO
- ...
- filp-gtf_op write_fifo_fops
- PIPE_WCOUNTER(inode)
- PIPE_WRITERS(inode)
- ...
-
26FIFO_OPEN(fs/fifo.c)
- case 3 // lectura y escritura
- filp-gtf_op rdwr_fifo_fops
- PIPE_READERS(inode)
- PIPE_WRITERS(inode)
- PIPE_RCOUNTER(inode)
- PIPE_WCOUNTER(inode)
- ....
- default
- ...
-
- / Ok! /
- up(PIPE_SEM(inode))
- unlock_kernel()
- return 0
-
27Operaciones de entradas/salidas
- Todas las operaciones de entradas/salidas, ya se
trate de tuberías con nombre o anónimas, se
encuentran en el archivo fs/pipe.c. - Las lecturas y las escrituras se efectúan en una
memoria intermedia de tamaño PIPE_BUF (4KB). En
función de las lecturas y escrituras de datos en
la tubería, la ventana que contiene los datos de
la tubería se desplaza de manera circular en el
interior de la memoria intermedia.
28Operaciones de entradas/salidas
- pipe_read ? recorre la página de memoria de la
tubería copiando los datos contenidos en la
memoria intermedia destinada al usuario. - Durante esta operación, la tubería se bloquea.
- Lectura sin bloqueo gt se devuelve el error
EAGAIN si la tubería está bloqueada o vacía. - Lectura con bloqueo gt el proceso que llama se
queda en espera mientras la tubería esté vacía.
29Operaciones de entradas/salidas
- pipe_write ? escritura en la tubería de datos
pasados como parámetros en la memoria intermedia,
dentro del límite de tamaño restante disponible. - Mientras dura la operación, los accesos a la
tubería están bloqueados. - Esta función efectúa un bucle hasta escribir
todos los datos en la tubería. - En cada pasada por el bucle, comprueba si quedan
procesos lectores en la tubería. Si es así, se
envía la señal SIGPIPE al proceso que llama. En
caso contrario, la tubería se bloquea, los datos
se copian desde la memoria intermedia
proporcionada por quien llama, y la tubería se
desbloquea.
30Operaciones de entradas/salidas
- pipe_ioctl ? la única operación de ioctl
permitida es la designada por FIONREAD, que
permite recuperar el número de bytes de datos
almacenados actualmente en al tubería. Se
devuelve el contenido de campo len de la
escritura pipe_inode_info
31Operaciones de entradas/salidas
- pipe_select ? para operación de multiplexado
asociada a la llamada select, esta función
verifica ciertas condiciones de validez antes de
indicar si es necesario volver a las entradas o
salidas sobre la tubería - multiplexado en lectura es necesario que la
tubería no esté vacía y que al menos un proceso
tenga acceso a la tubería en escritura - multiplexado en escritura es necesario que la
tubería no esté llena y que al menos un proceso
tenga acceso a la tubería en lectura - excepciones la tubería debe ser accesible al
menos por un proceso en lectura y en escritura
32Operaciones de entradas/salidas
- Se utilizan estas funciones únicamente en el
contexto de las tuberías con nombre, cuando al
crear la tubería, ningún proceso ha abierto la
tubería en escritura - connect_read ? Sólo modifica las operaciones
realizables sobre el i-nodo asignando el campo
f_op a read_fifo_fops. Tras esta modificación, se
lanza una llamada a la función de lectura en una
tubería (pipe_read).
33Operaciones de entradas/salidas
- connect_select ? Esta función modifica el campo
f_op en el caso del multiplexado en lectura.
34Operaciones de entradas/salidas
- Se utilizan estas funciones para cerrar
descriptores - pipe_read_release ? decrementa nºprocesos
con acceso en lectura a la tubería - pipe_write_release ? decrementa nºprocesos con
acceso en escritura a la tubería - pipe_rdwr_release ? decrementa nºprocesos
con acceso en lectura y escritura a la tubería
35Operaciones de entradas/salidas
- Se utilizan estas funciones para creación de un
nuevo proceso que hereda la tubería - pipe_read_open ? incrementa nºprocesos con acceso
en lectura a la tubería - pipe_read_open(struct inode inode, struct file
filp) -
- down(PIPE_SEM(inode))
- PIPE_READERS(inode)
- up(PIPE_SEM(inode))
36Operaciones de entradas/salidas
- pipe_write_open ? incrementa nºprocesos con
acceso en escritura a la tubería. - pipe_write_open(struct inode inode, struct file
filp) -
- down(PIPE_SEM(inode))
- PIPE_WRITERS(inode)
- up(PIPE_SEM(inode))
37Operaciones de entradas/salidas
- pipe_rdwr_open ? incrementa nºprocesos con acceso
en lectura y escritura a la tubería. - pipe_rdwr_open(struct inode inode, struct
filefilp) -
- down(PIPE_SEM(inode))
- if (filp-gtf_mode FMODE_READ)
- PIPE_READERS(inode)
- if (filp-gtf_mode FMODE_WRITE)
- PIPE_WRITERS(inode)
- up(PIPE_SEM(inode))
-