Scatter-gather - readv()/ writev()/ preadv()/ pwritev() - 在单个系统调用中读/写可变数量的iovec结构.基本上它从第0个iovec到第N个顺序读/写每个缓冲区.但是根据文档,它在readv/writev调用上的返回次数也少于请求的次数.我想知道是否有一种标准/最佳实践/优雅方式来处理这种情况.
如果我们只是处理一堆字符缓冲区或类似的东西,这不是什么大问题.但其中一个细节是使用分散 - 聚集结构和/或离散变量作为单独的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?.........
Run Code Online (Sandbox Code Playgroud)
R..*_*R.. 11
使用如下所示的循环来推进部分处理的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;
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果您没有检查,cur < count那么您将阅读其结尾iov可能包含零.