En informática , la E/S vectorizada , también conocida como E/S scatter/gather , es un método de entrada y salida mediante el cual una única llamada a un procedimiento lee secuencialmente datos de varios búferes y los escribe en un único flujo de datos (gather), o lee datos de un flujo de datos y los escribe en varios búferes (scatter), tal como se define en un vector de búferes. Scatter/gather se refiere al proceso de recopilar datos de, o dispersar datos en, el conjunto dado de búferes. La E/S vectorizada puede funcionar de forma sincrónica o asincrónica. Las principales razones para utilizar la E/S vectorizada son la eficiencia y la comodidad.
La E/S vectorial tiene varios usos potenciales:
Los organismos de normalización documentan las funciones aplicables readv
[1] y writev
[2] en POSIX 1003.1-2001 y la versión 2 de la Especificación Única UNIX. La API de Windows tiene funciones análogas ReadFileScatter
y WriteFileGather
; sin embargo, a diferencia de las funciones POSIX, requieren la alineación de cada búfer en una página de memoria . [3] Winsock proporciona funciones WSASend
y independientes WSARecv
sin este requisito.
Si bien trabajar directamente con un vector de buffers puede ser significativamente más difícil que trabajar con un solo buffer, el uso de API de nivel superior [4] para trabajar de manera eficiente puede mitigar las dificultades.
El siguiente ejemplo en lenguaje de programación C imprime "Hola, comunidad de Wikipedia" en la salida estándar . Cada palabra se guarda en un único búfer y con una sola llamada a writev()
, todos los búferes se imprimen en la salida estándar.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/uio.h> int main ( int argc , char * argv []) { const char buf1 [] = "Hola, " ; const char buf2 [] = "Wikipedia " ; const char buf3 [] = "¡Comunidad! \n " ; estructura iovec bufs [ ] = { { .iov_base = ( void * ) buf1 , .iov_len = strlen ( buf1 ) } , { .iov_base = ( void * ) buf2 , .iov_len = strlen ( buf2 ) } , { .iov_base = ( void * ) buf3 , .iov_len = strlen ( buf3 ) } , } ; si ( writev ( STDOUT_FILENO , bufs , sizeof ( bufs ) / sizeof ( bufs [ 0 ])) == -1 ) { perror ( "writev()" ); salir ( EXIT_FAILURE ); } devolver SALIDA_EXITO ; }