Advanced Programming in UNIX Environment Episode 81

readv and writev Functions

The readv and writev functions let us read into and write from multiple noncontiguous buffers in a single function call. These operations are called scatter read and gather write.

#include <sys/uio.h>
ssize_t readv(int fd, const struct iovec *iov, int iovcnt);
ssize_t writev(int fd, const struct iovec *iov, int iovcnt);

The second argument to both functions is a pointer to an array of iovec structures:

struct iovec {
	void *iov_base; /* starting address of buffer */
	size_t iov_len; /* size of buffer */
};

The number of elements in the iov array is specified by iovcnt. It is limited to IOV_MAX.

The readv function scatters the data into the buffers in order, always filling one buffer before proceeding to the next. readv returns the total number of bytes that were read. A count of 0 is returned if there is no more data and the end of file is encountered.

These two functions originated in 4.2BSD and were later added to SVR4. These two functions are included in the XSI option of the Single UNIX Specification.

The second buffer to output is an argument passed by the caller, and the first buffer is one we create, containing the length of the second buffer and a file offset of other information in the file. There are three ways we can do this.

1.Call write twice, once for each buffer.
2.Allocate a buffer of our own that is large enough to contain both buffers, and copy both into the new buffer. We then call write once for this new buffer.
3.Call writev to output both buffers.

The fixed cost of using writev for such small amounts of data, however, is greater than the benefit. As the amount of data we need to copy increases, the more expensive it will be to copy the buffers in our program, and the writev alternative will be more attractive.

Don’t infer too much about the relative performance of Linux and Mac OS X from the numbers shown in Figure 14.23. The two computers were very different: they had different processor generations, different amounts of RAM, and disks with different speeds. To do an apples-toapples comparison of one operating system to another, we need to use the same hardware for each operating system.

readn and writen Functions

Pipes, FIFOs, and some devices—notably terminals and networks—have the following two properties.
1.A read operation may return less than asked for, even though we have not encountered the end of file. This is not an error, and we should simply continue reading from the device.
2.A write operation can return less than we specified. This may be caused by kernel output buffers becoming full, for example. Again, it’s not an error, and we should continue writing the remainder of the data. (Normally, this short return from a write occurs only with a nonblocking descriptor or if a signal is caught.)

#include "apue.h"
ssize_t readn(int fd, void *buf, size_t nbytes);
ssize_t writen(int fd, void *buf, size_t nbytes);

We define these functions as a convenience for later examples, similar to the error-handling routines used in many of the examples in this text. The readn and writen functions are not part of any standard.

#include "apue.h"

ssize_t readnint fd, void *ptr, size_t n)
{
    size_t nleft;
    ssize_t nread;

    nleft=n;
    while(nleft>0)
    {
        if((nread=read(fd, ptr, nleft))<0)
        {
            if(nleft==n)
                return -1;
            else
                break;
        }
        else if(nread==0)
        {
            break;
        }
        nleft-=nread;
        ptr+=nread;
    }

    return n-nleft;
}

ssize_t writen(int fd, const void *ptr, size_t n)
{
    size_t nleft;
    ssize_t nwritten;
    
    nleft=n;
    while(nleft>0)
    {
        if((nwritten=write(fd, ptr, nleft))<0)
        {
            if(nleft==n)
                return -1;
            else
                break;
        }
        else if(nwritten==0)
        {
            break;
        }
        nleft-=nwritten;
        ptr+=nwritten;
    }

    return n-nleft;
}

The readn and writen functions

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值