splice () es una llamada al sistema específica de Linux que mueve datos entre un descriptor de archivo y una tubería sin un viaje de ida y vuelta al espacio del usuario. La llamada al sistema relacionada vmsplice () mueve o copia datos entre una tubería y el espacio de usuario. Idealmente, splice y vmsplice funcionan reasignando páginas y en realidad no copian ningún dato, lo que puede mejorar elrendimiento de E / S. Como las direcciones lineales no se corresponden necesariamente con direcciones físicas contiguas, esto puede no ser posible en todos los casos y en todas las combinaciones de hardware.
Funcionamiento
Con splice () , uno puede mover datos de un descriptor de archivo a otro sin incurrir en ninguna copia del espacio del usuario al espacio del kernel, que generalmente se requiere para hacer cumplir la seguridad del sistema y también para mantener una interfaz simple para que los procesos lean y escriban en archivos. splice () funciona utilizando el búfer de tubería . Un búfer de tubería es un búfer de memoria en el núcleo que es opaco para el proceso del espacio de usuario. Un proceso de usuario puede empalmar el contenido de un archivo de origen en este búfer de tubería y luego empalmar el búfer de tubería en el archivo de destino, todo sin mover ningún dato a través del espacio de usuario.
Linus Torvalds describió splice () en un correo electrónico de 2006, que se incluyó en un artículo de KernelTrap . [1]
Orígenes
La implementación de empalme de Linux toma prestadas algunas ideas de una propuesta original de Larry McVoy en 1998. [2] Las llamadas al sistema de empalme aparecieron por primera vez en la versión 2.6.17 del kernel de Linux y fueron escritas por Jens Axboe .
Prototipo
ssize_t splice ( int fd_in , loff_t * off_in , int fd_out , loff_t * off_out , size_t len , banderas int sin firmar );
Algunas constantes que son de interés son:
/ * Banderas de empalme (aún no grabadas en piedra). * / #Ifndef SPLICE_F_MOVE #define SPLICE_F_MOVE 0x01 #endif #ifndef SPLICE_F_NONBLOCK #define SPLICE_F_NONBLOCK 0x02 #endif #ifndef SPLICE_F_MORE #define SPLICE_F_MORE 0x04 #endif #ifndef SPLICE_F_GIFT #define SPLICE_F_GIFT 0x08 #endif
Ejemplo
Este es un ejemplo de empalme en acción:
/ * Transferir del disco a un registro. * / int log_blocks ( struct log_handle * handle , int fd , loff_t offset , size_t size ) { int filedes [ 2 ]; int ret ; size_t to_write = tamaño ; ret = tubería ( filedes ); si ( ret < 0 ) goto out ; / * empalmar el archivo en la tubería (datos en la memoria del kernel). * / while ( to_write > 0 ) { ret = splice ( fd , & offset , filedes [ 1 ], NULL , to_write , SPLICE_F_MORE | SPLICE_F_MOVE ); if ( ret < 0 ) goto pipe ; else to_write - = ret ; } to_write = tamaño ; / * empalmar los datos en la tubería (en la memoria del kernel) en el archivo. * / while ( to_write > 0 ) { ret = splice ( filedes [ 0 ], NULL , handle -> fd , & ( handle -> fd_offset ), to_write , SPLICE_F_MORE | SPLICE_F_MOVE ); if ( ret < 0 ) goto pipe ; else to_write - = ret ; }pipe : close ( filedes [ 0 ]); cerrar ( filedes [ 1 ]); out : if ( ret < 0 ) return - errno ; return 0 ; }
Llamadas al sistema complementarias
splice () es una de las tres llamadas al sistema que completan el arquitectura de empalme () . vmsplice () puede mapear un área de datos de aplicación en una tubería (o viceversa), permitiendo así transferencias entre tuberías y la memoria del usuario donde sys_splice () transfiere entre un descriptor de archivo y una tubería. tee () es la última parte de la trilogía. Duplica una tubería a otra, lo que permite horquillas en la forma en que las aplicaciones se conectan con las tuberías.
Requisitos
Cuando usas splice () con sockets, el controlador de red (NIC) debe admitir DMA; de lo contrario, splice () no ofrecerá una gran mejora de rendimiento. La razón de esto es que cada página de la tubería se llenará hasta el tamaño del marco (1460 bytes de los 4096 bytes disponibles por página).
No todos los tipos de sistemas de archivos son compatibles empalme () . También, Los zócalos AF_UNIX no son compatibles empalme () .
Ver también
Referencias
- ^ "Linux: Explicación de empalme () y tee ()" . kerneltrap.org. 2006-04-21. Archivado desde el original el 21 de mayo de 2013 . Consultado el 27 de abril de 2014 .
- ^ "Copia archivada" . Archivado desde el original el 4 de marzo de 2016 . Consultado el 28 de febrero de 2016 .Mantenimiento de CS1: copia archivada como título ( enlace )
enlaces externos
- Kernel de Linux 2.6.17 (kernelnewbies.org)
- Dos nuevas llamadas al sistema: splice () y sync_file_range () ( LWN.net )
- Algunas llamadas al sistema nuevas (LWN.net)