使用分散处理来处理短读/写操作的技巧?

Scatter-gather – readv()/ writev()/ preadv()/ pwritev() – 在单个系统调用中读取/写入可变数目的iovec结构体。 基本上它从0到iN依次读/写每个缓冲区。 然而,根据文档,readv / writev调用的返回次数也比请求的less。 我想知道是否有一个标准/最佳做法/优雅的方式来处理这种情况。

如果我们只是处理一堆字符缓冲区或类似的东西,这不是什么大问题。 但其中的一个优点是使用分散收集结构和/或离散variables作为个人iovec项目。 如何处理readv / writev只读取/写入结构的一部分或长度的一半或类似的情况。

下面是我正在做的一些人为的代码:

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?......... 

Solutions Collecting From Web of "使用分散处理来处理短读/写操作的技巧?"

使用如下循环来推进部分处理的iov:

 for (;;) { written = writev(fd, iov+cur, count-cur); if (written < 0) goto error; while (cur < count && written >= iov[cur].iov_len) written -= iov[cur++].iov_len; if (cur == count) break; iov[cur].iov_base = (char *)iov[cur].iov_base + written; iov[cur].iov_len -= written; } 

请注意,如果您不检查cur < count您将读取可能包含零的iov结尾。

AFAICS向量化的读/写功能与正常的读写功能一样。 也就是说,您可以获取读/写的字节数,但这可能会指向结构的中间,就像read()/ write()一样。 不能保证可能的“中断点”(因缺少更好的术语)与矢量边界一致。 所以,不幸的是,向量IO函数提供的处理读取/写入操作比正常的IO函数没有更多的帮助。 实际上,由于需要将字节数映射到元素中的IO向量元素和偏移量,因此更为复杂。

还要注意,使用向量化IO来实现单个结构或数据项目的想法可能不会奏效。 iovcnt参数的最大允许值(IOV_MAX)通常很小,大约为1024左右。 所以如果你的数据在内存中是连续的,只需要把它作为一个单独的元素来传递,而不是人为地分割它。

向量化写入将把您提供的所有数据通过一次调用写入“writev”函数。 所以字节写入总是等于提供的输入字节总数。 这是我的理解。

如果我错了,请纠正我