Reputation: 50550
Consider the documentation of uv_try_write
(the same applies for uv_write
and uv_write2
as well).
The declaration is:
int uv_try_write(uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs)
Where uv_buf_t
is a data structure that has at least the following fields:
char* uv_buf_t.base
size_t uv_buf_t.len
I'm quite sure I'm missing something here.
What's the reason for which one should submit more than one uv_buf_t
structure instead of a bigger one?
In other terms, if I have 100 char
to write out, why should I submit 10 uv_buf_t
containing each 10 char
instead of a uv_buf_t
containing 100 char
?
It would be helpful a real world example in which such a choice makes sense, for I can't figure out it while reading the documentation.
Upvotes: 3
Views: 1017
Reputation: 16136
Whenever you perform formatted I/O, all you are doing is concatenating a bunch of small strings.
Think about what is happening under the hood when you write something like
fprintf(stdout, "Hello, %s!\n", getenv("USER"));
This could be implemented (ignoring the multiple evaluation of getenv
) as:
struct iovec bufs[3] = {{"Hello, ", 7}, {getenv("USER"), strlen(getenv("USER"))}, {"!\n", 2}};
writev(STDOUT_FILENO, bufs, 3);
(in practice, FILE
operations are a little more complicated - perhaps unnecessarily so - but most cases are this simple).
Allowing multiple buffers to be specified directly means that you don't have to waste process time (or source code complexity) allocating a single buffer to hold them all before writing.
Also, have you ever run an compiler under make -j
such that its output gets hugely messed up? That is generally caused because they do not do this - instead they emit several individual write
s and they get mixed with writes from parallel processes, rather than emitting each line during a single syscall.
Upvotes: 2
Reputation: 2010
Most applications probably use a single one, but since writev
is a thing we expose it in the try variant as well. Imagine an application which behaves as a proxy, and gets data in multiple packets which it then needs to relay. Sensing all buffers belonging to the same packet in a single go limits the syscalls to 1, instead of having to allocate space for all buffers, then copying over the content just to call write
.
You can read more about the approach here: https://en.wikipedia.org/wiki/Vectored_I/O
Upvotes: 1