c++ - 当端口上有字符时,select() 调用不返回

标签 c++ linux select

我有一个 select 调用似乎没有检测到串行端口上的字符。我有什么想念的吗?

如果我删除上面 block 中的 read() 代码,select 将返回一段时间,直到现有端口缓冲区被清空,然后不再检测到任何内容。

我正在将字符流式传输到端口,运行 minicom 显示端口上有连续的输入流。

有人能看出这段代码有什么问题吗?

int main(void)

{


  int ret;
  char buf[1280];
  fd_set         m_Inputs;  // fd_set for the select call for com input

  int            m_maxFD;   // max FD for select() call.

  struct timeval tv;



  int fd1;
  fd1 = open("/dev/ttyXR6", O_RDWR | O_NOCTTY | O_NONBLOCK);

  fcntl(fd1, F_SETFL, 0);

  struct termios options;

  tcgetattr(fd1, &options);  // Get the current options for the port...

  // Set the baud rates...
  cfsetispeed(&options, B9600);
  cfsetospeed(&options, B9600);

  // Enable the receiver and set local mode...
  options.c_cflag |= (CLOCAL | CREAD | CS8);
  options.c_cflag &= ~PARENB;  // ignore parity
  options.c_cflag &= ~CSTOPB;  // 1 stop bit (2 if set)
  options.c_cflag &= ~CSIZE;   // clear the size bits
  options.c_cflag &= ~CRTSCTS; //No hard flow control
  options.c_cflag &= ~HUPCL;   //Hang Up on last Close
  options.c_cflag |= CS8;      // reset the size to 8 bits / char
  options.c_cc[VMIN]=1;
  options.c_cc[VTIME] = 1;
  options.c_oflag = 0;
  options.c_lflag = 0;       //ICANON;
  // Set the new options for the port...
  tcsetattr(fd1, TCSANOW, &options);

  // test to make sure the characters are coming in on the port

  for (short i =0; i < 60; i++)
  {
    ret = read(fd1, buf, 32);
    buf[ret] = '\0';
    cout << buf;
    usleep(500);
  }

  fd_set         rfds;  // fd_set for the select call for com input

  FD_ZERO(&rfds);

  FD_SET(fd1, &rfds);


  cout << endl << "FD1 = " << fd1 << endl;

  while (1)
  {
    tv.tv_sec = 0;

    tv.tv_usec = 1000;

    ret = select(fd1 + 1, &rfds, NULL, NULL, &tv);


    if (ret > 0)

    {
      ret = read(fd1, buf, 127);
      buf[ret] = '\0';
      cout << buf;
    }
    usleep(500);
  }

  return 0;

}

最佳答案

在返回之前,select() 修改 rfds 以指示哪些描述符已准备好读取数据。

在您的情况下,它在达到 1 毫秒超时后第一次返回并且您的描述符上没有可用数据时,它将从 rfds 集中删除您的描述符以指示没有可用数据。然后,当你在下一次循环中再次调用 select() 时,rfds 是一个空集,所以在那之后它甚至不会再检查你的描述符了。

每次循环时都需要在选择之前调用 FD_SET(fd1, &rfds)。

关于c++ - 当端口上有字符时,select() 调用不返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1344011/

相关文章:

c++ - 高阶位——把它们变成 uint64_t 变成 uint8_t

c++ - 为什么我在 for 循环中收到 'Else without previous if' 错误?

c++ - 简单的 C++ 声音 API

Javascript 填充选择框

c++ - Visual Studio 2010 随机停止构建

c++ - Z3 不饱和核心 : an assumption must be a propositional variable or the negation of one

linux - 识别进程的资源使用情况 : CPU, 内存和 I/O

linux - 从无线设备驱动程序获取比特率的值。

javascript - 使用 Angular 从下拉列表中获取选定的值

javascript - html 选择列表 - 通过传入变量获取文本值?