La comodità principale offerto da readv
, writev
è:
- Esso permette di lavorare con blocchi non contigui di dati. Ad esempio, i buffer hanno bisogno di non essere parte di un array, ma allocati separatamente.
- L'I/O è "atomico". Ad esempio, se si fa un
writev
, tutti gli elementi nel vettore verranno scritti in un'operazione contigua e le scritture eseguite da altri processi non si verificheranno tra di essi.
ad es. per esempio, i dati sono naturalmente segmentato, e proviene da fonti diverse:
struct foo *my_foo;
struct bar *my_bar;
struct baz *my_baz;
my_foo = get_my_foo();
my_bar = get_my_bar();
my_baz = get_my_baz();
Ora, tutti e tre i 'buffer' sono non un unico grande blocco contiguo. Ma vuoi scriverli in modo contiguo in un file, per qualsiasi motivo (ad esempio, sono campi in un'intestazione di file per un formato di file).
Se si utilizza write
devi scegliere tra:
- li Copiare in un unico blocco di memoria utilizzando, per esempio,
memcpy
(overhead), seguito da un singolo write
chiamata. Quindi la scrittura sarà atomica.
- Effettuare tre chiamate separate a
write
(overhead). Inoltre, le chiamate write
da altri processi possono intersperse tra queste scritture (non atomiche).
Se si utilizza writev
invece, è tutto buono:
- Si fanno esattamente una chiamata di sistema, e non
memcpy
per fare un singolo buffer da tre.
- Inoltre, i tre buffer sono scritti atomicamente, come una scrittura di blocco. cioè se anche altri processi scrivono, allora queste scritture non verranno tra le scritture dei tre vettori.
Così si farebbe qualcosa di simile:
struct iovec iov[3];
iov[0].iov_base = my_foo;
iov[0].iov_len = sizeof (struct foo);
iov[1].iov_base = my_bar;
iov[1].iov_len = sizeof (struct bar);
iov[2].iov_base = my_baz;
iov[2].iov_len = sizeof (struct baz);
bytes_written = writev (fd, iov, 3);
Fonti:
- http://pubs.opengroup.org/onlinepubs/009604499/functions/writev.html
- http://linux.die.net/man/2/readv
Nel 'Linux Sistema programming' libro, dicono' readv o writev può verificarsi con qualsiasi gli errori delle chiamate di sistema read() e write() e, dopo aver ricevuto tali errori, impostano gli stessi codici errno. Quindi readv restituirà 'EINTR'? O cosa succederà a un segnale che si verifica tra la lettura atomica di readv? sarà ignorato o accodato. – nmxprime
@nmxprime se il segnale arriva durante 'readv()' o 'writev()', queste syscalls (a seconda di SA_RESTART) restituiranno meno byte di quanto richiesto. – socketpair
Posso scrivere il buffer non contiguo nel file in modo non contiguo e non come un blocco intero? – RAFA