【问题标题】:How to use select() correctly inside a loop?如何在循环中正确使用 select()?
【发布时间】:2020-12-05 04:53:35
【问题描述】:

我正在尝试修改我找到的示例。

例子:

#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#define STDIN 0  // file descriptor for standard input

int main(void)
{
   struct timeval tv;
   fd_set readfds;

   tv.tv_sec = 2;
   tv.tv_usec = 500000;

   FD_ZERO(&readfds);
   FD_SET(STDIN, &readfds);

   // don't care about writefds and exceptfds:
   select(STDIN+1, &readfds, NULL, NULL, &tv);

   if (FD_ISSET(STDIN, &readfds))
       printf("A key was pressed!\n");
   else
       printf("Timed out.\n");

   return 0;
}

如果 2.5 秒后没有发送消息,则打印超时,否则打印一个键。

我试图把它放在一个while循环中:

#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#define STDIN 0  // file descriptor for standard input

int main(void)
{
   fd_set readfds, temp;
   struct timeval tv;

   FD_ZERO(&readfds);
   FD_ZERO(&temp);
   FD_SET(STDIN, &readfds);

   while(1){
       
   temp = readfds;     
   tv.tv_sec = 2;
   tv.tv_usec = 500000;
   // don't care about writefds and exceptfds:
   if (select(STDIN+1, &temp, NULL, NULL, &tv) == -1)
       printf("err");

   if (FD_ISSET(STDIN, &temp))
   {
       printf("A key was pressed!\n");
   }
   else
       printf("Timed out.\n");
   }
   return 0;
} 

在这段代码中,当我输入一个键时,它会一直打印一个键被永远按下。

我在网上阅读了我每次都必须设置 tv 变量但仍然没有帮助。

我需要临时工吗fd_set ?我怎么了?

【问题讨论】:

  • 代码缩进不正确可能会让 oyu 出错。请修复它。
  • 查找您从select() 获得的返回值以及它对temp 内容的含义。另外:-1 返回不是错误。
  • 你永远不会从 fd 读取,所以当然它是可读的。

标签: c linux sockets networking gnu


【解决方案1】:
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>

                // Note: STDIN_FILENO, or fileno(stdin)
#define STDIN 0  // file descriptor for standard input

int main(void)
{
   fd_set readfds, temp;
   struct timeval tv;
   int ret,ch;

   FD_ZERO(&readfds);
   FD_ZERO(&temp);
   FD_SET(STDIN, &readfds);

   while(1){

        temp = readfds;
        tv.tv_sec = 2;
        tv.tv_usec = 500000;
        // don't care about writefds and exceptfds:
        ret = select(STDIN+1, &temp, NULL, NULL, &tv) ;
        if (ret == -1) {
                if (errno == EAGAIN) continue; // These are NOT Errors, but natural occuring events
                if (errno == EINTR) continue; // The are reported to avoid your select() to block for too long
                        perror("erreur");
                break;
                }
        else if (ret ==0) {
           printf("Timed out.\n");
                continue;
                }
                // Ok: select has returned > 0; there must be something to read
        if (FD_ISSET(STDIN, &temp)) {
                ch = getc(stdin); // Lookout: stdin is line-buffered
                printf("A key was pressed: %d!\n", ch);
                }
        }
   return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-04
    • 2021-10-19
    • 1970-01-01
    • 1970-01-01
    • 2021-03-25
    相关资源
    最近更新 更多