Dans la dispersion et la collecte (c.-à-d. readv
et writev
), Linux lit plusieurs tampons et écrit à partir de plusieurs tampons.
Si, par exemple, j’ai un vecteur de 3 tampons, je peux utiliser readv
, OU je peux utiliser un seul tampon, qui est de taille combinée de 3 tampons et qui fait du fread
.
Par conséquent, je suis confus: pour quels cas la dispersion / collecte devrait-elle être utilisée et quand un seul grand tampon devrait-il être utilisé?
La commodité principale offerte par readv
, writev
est:
writev
, tous les éléments du vecteur seront écrits dans une opération contiguë, et les écritures effectuées par d’autres processus ne se produiront pas entre elles. Par exemple, 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 quelque raison que ce soit (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
(overhead), suivi d’un seul appel en write
. Alors l’écriture sera atomique. write
(overhead). En outre, les appels d’ write
provenant d’autres processus peuvent s’intercaler entre ces écritures (non atomiques). Si vous utilisez plutôt writev
, tout va bien:
memcpy
pas créer un seul tampon à partir des trois. Donc, vous feriez 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: