【问题标题】:Confusion with select() - stdout never ready for write与 select() 混淆 - 标准输出从未准备好写入
【发布时间】:2015-08-28 08:36:10
【问题描述】:

这是一个简单的 select() 循环:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/select.h>

#define BUFSIZE 999

int main()
{
    int            select_result;
    fd_set         read_fds, write_fds;
    struct timeval timeout = {0, 400000}, timeoutcopy;
    const int max_fd = STDIN_FILENO > STDOUT_FILENO ? STDIN_FILENO :
                                                      STDOUT_FILENO;
    char buffer[BUFSIZE];

    fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) | O_NONBLOCK);
    fcntl(STDOUT_FILENO, F_SETFL, fcntl(STDOUT_FILENO, F_GETFL) | O_NONBLOCK);
    printf("Enter loop\n");
    while(1) {
        FD_ZERO(&read_fds);
        FD_ZERO(&write_fds);
        printf("Loop\n");
        FD_SET(STDIN_FILENO, &read_fds);
        FD_SET(STDOUT_FILENO, &write_fds);

        timeoutcopy = timeout;
        if ((select_result = select(max_fd, &read_fds, &write_fds, NULL,
                                    &timeoutcopy)) < 0) {
            return select_result;
        }

        if (FD_ISSET(STDIN_FILENO, &read_fds))
            printf("Stdin ready for read\n");
            fgets(buffer, BUFSIZE, stdin);
            if (strlen(buffer))
                printf("Stdin content: %s\n", buffer);
        if (FD_ISSET(STDOUT_FILENO, &write_fds))
            printf("Stdout ready for write\n");
    }
}

它只是用select() 轮询stdinstdout,超时时间为400000 毫秒。当stdin 准备好时,它会尝试读取它的内容并打印它。当stdout 准备就绪时,它只会打印它准备就绪。

而且由于某种原因,在select() 之后调用stdin 永远不会准备好,为什么?

【问题讨论】:

  • 在复制代码时,您是否在if (FD_ISSET(STDIN_FILENO, &amp;read_fds)) 之后错过了大括号{...} ... 如所写,它将始终运行fgets(),因此(我认为)没有/很少机会用于输入字符以使 stdin 准备就绪。

标签: c unix select io


【解决方案1】:

您的max_fd 应该是“三组中任何一个中编号最高的文件描述符,加 1”。根据选择手册页。我应该重命名它,以便您记得添加 1。

【讨论】:

    【解决方案2】:

    max_fd 必须加 1。这个名字确实令人困惑,“nfds”可能更清楚。请看这里:

    select man page

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-08
      • 2012-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-01
      相关资源
      最近更新 更多