Dispersión-recopilar - readv()/writev()/preadv()/pwritev() - lecturas/escrituras un número variable de estructuras iovec en una sola llamada al sistema. Básicamente lee/escribe cada buffer de forma secuencial desde el 0 ° iovec hasta el N °. Sin embargo, según la documentación, también puede devolver menos en las llamadas de lectura/escritura de lo solicitado. Me preguntaba si existe una forma estándar/mejor práctica/elegante para manejar esa situación.Técnicas para manejar lecturas cortas/escrituras con scatter-gather?
Si sólo estamos manejando un grupo de buffers de caracteres o similar, esto no es un gran problema. Pero una de las sutilezas es usar scatter-gather para estructuras y/o variables discretas como elementos individuales de iovec. ¿Cómo se maneja la situación en la que readv/writev solo lee/escribe una parte de una estructura o la mitad de una larga o algo así?
A continuación se muestra un código artificial de lo que quiero decir:
int fd;
struct iovec iov[3];
long aLong = 74775767;
int aInt = 949;
char aBuff[100]; //filled from where ever
ssize_t bytesWritten = 0;
ssize_t bytesToWrite = 0;
iov[0].iov_base = &aLong;
iov[0].iov_len = sizeof(aLong);
bytesToWrite += iov[0].iov_len;
iov[1].iov_base = &aInt;
iov[1].iov_len = sizeof(aInt);
bytesToWrite += iov[1].iov_len;
iov[2].iov_base = &aBuff;
iov[2].iov_len = sizeof(aBuff);
bytesToWrite += iov[2].iov_len;
bytesWritten = writev(fd, iov, 3);
if (bytesWritten == -1)
{
//handle error
}
if (bytesWritten < bytesToWrite)
//how to gracefully continue?.........
Bien, R, eso es exactamente lo que estaba buscando. Puntero aritmético al rescate. ¿Considera que los resultados cortos de lectura/escritura son una condición común en lugar de una excepción, como en la lectura/escritura estándar y esto es algo que siempre debe codificarse? – ValenceElectron
Sí. Con pipes, Sockets o ttys en modo nonblocking, las escrituras cortas son la norma. Pero incluso en otras situaciones, pueden ser poco probable, pero aún una posibilidad real. Incluso si 'SA_RESTART' se usa para el manejador de señal, si' writev' es interrumpido por una señal, solo se reiniciará si aún no se ha escrito nada. Si ya se completó una escritura parcial, devolverá la escritura corta. Incluso si no tiene controladores de señal, el proceso se detiene y se reanuda con 'SIGSTOP' (no bloqueable) y' SIGCONT' tendrá los mismos efectos. –
Por cierto, acabo de arreglar mi código. Olvidé que 'iov_base' tiene el tipo' void * 'y, por lo tanto, la aritmética no es válida. La nueva versión se convierte en 'char *' para realizar la aritmética. –