Dans scatter et rassembler (c'est-à-dire readv
et writev
), Linux lit dans plusieurs tampons et écrit à partir de plusieurs tampons.
Si disons, j'ai un vecteur de 3 tampons, je peux utiliser readv
, OR je peux utiliser un seul tampon, qui est de taille combinée de 3 tampons et faire fread
.
Par conséquent, je suis confus: pour quels cas la diffusion/collecte doit-elle être utilisée et quand utiliser un seul grand tampon?
La principale commodité offerte par readv
, writev
est:
writev
, tous les éléments du vecteur seront écrits en une seule opération contiguë, et les écritures effectuées par d'autres processus ne se produiront pas entre eux.par exemple. disons, vos données sont naturellement segmentées et proviennent de différentes sources:
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();
Maintenant, les trois 'tampons' ne sont pas un gros bloc contigu. Mais vous voulez les écrire de manière contiguë dans un fichier, pour une raison quelconque (disons par exemple, ce sont des champs dans un en-tête de fichier pour un format de fichier).
Si vous utilisez write
, vous devez choisir entre:
memcpy
(surcharge), suivi d'un seul appel write
. L'écriture sera alors atomique.write
(frais généraux). De plus, les appels write
provenant d'autres processus peuvent se propager entre ces écritures (non atomiques).Si vous utilisez writev
à la place, tout va bien:
memcpy
pour créer un seul tampon à partir des trois.Vous feriez donc quelque chose comme:
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);
Sources: