在“Linux系统编程”一书的第34页上,给出了用while循环正确处理部分读取以阻塞读取的以下示例

ssize_t ret;

while (len != 0 && (ret = read(fd, buf, len)) != 0) {
    if (ret == -1) {
        if (errno == EINTR)
            continue;
        perror("read");
        break;
    }

    len -= ret;
    buf += ret;
}

在下一页中,它给出了以下非阻塞读取的示例。此示例是否需要包装在while循环中以处理部分读取的可能性?
char buf[BUFSIZ];
ssize_t nr;

start:
nr = read(fd, buf, BUFSIZ);
if (nr == -1) {
    if (errno == EINTR)
        goto start; /* oh shush */
    if (erron == EAGAIN)
        /* resubmit later */
    else
        /* error */
}

最佳答案

通常,当代码可以(或打算)并行执行其他操作,而不是等待输入(例如,检查另一个文件或套接字)时,使用非阻塞IO。否则,正如Jlghtuse所提到的,一个简单的阻塞IO将执行与在文件上轮询读取相同的技巧。但是,我不确定非阻塞IO是否保证返回请求的确切字节数。作为一个安全的赌注,它可能需要一个while循环。我认为一个可用的代码块可能看起来像:

char buf[BUFSIZ];
ssize_t nr;
char *bufp = buf;
ssize_t rdbyts = 0;

while(rdbyts < BUFSIZ) {
    nr = read(fd, bufp, (BUFSIZ - rdbyts));
    if (nr == -1) {
        if (errno == EINTR)
            continue; /* oh shush */
        else if (errno == EAGAIN)
            /* resubmit later - might be do
             * something else and come back
             * or just sleep. */
            do_some_work_or_sleep();
            continue;
        else
            /* error */
            break;
    } else if (nr < (BUFSIZ - rdbytes)) {
        bufp += nr;
        rdbyts += nr;
    }
}

关于c - 非阻塞模式下的部分读取,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20090235/

10-12 01:25
查看更多