OpenBSD串行I / O:即使使用termios VTIME设置,-lpthead也能永久地生成read()块?

时间:2013-04-11 23:13:15

标签: serial-port pthreads openbsd

我有一个FTDI USB串行设备,我通过termios串行API使用。我设置了端口,以便在半秒内通过read()调用超时(通过使用VTIME参数),这适用于Linux和FreeBSD。但是,在OpenBSD 5.1上,当没有数据可用时,read()调用会永远阻塞(见下文)。我希望read()在500ms后返回0。

有没有人能想到在OpenBSD下termios API会有不同的行为,至少在超时功能方面呢?

编辑:无超时问题是由链接到pthread引起的。无论我是否实际使用任何pthread,互斥锁等,只需链接到该库会导致read()永久阻塞,而不是基于VTIME设置超时。同样,这个问题只体现在OpenBSD上 - Linux和FreeBSD按预期工作。

if ((sd = open(devPath, O_RDWR | O_NOCTTY)) >= 0)
{
  struct termios newtio;
  char input;

  memset(&newtio, 0, sizeof(newtio));

  // set options, including non-canonical mode
  newtio.c_cflag = (CREAD | CS8 | CLOCAL);
  newtio.c_lflag = 0;

  // when waiting for responses, wait until we haven't received
  // any characters for 0.5 seconds before timing out
  newtio.c_cc[VTIME] = 5;
  newtio.c_cc[VMIN] = 0;

  // set the input and output baud rates to 7812
  cfsetispeed(&newtio, 7812);
  cfsetospeed(&newtio, 7812);

  if ((tcflush(sd, TCIFLUSH) == 0) &&
      (tcsetattr(sd, TCSANOW, &newtio) == 0))
  {
    read(sd, &input, 1); // even though VTIME is set on the device,
                         // this read() will block forever when no
                         // character is available in the Rx buffer
  }
}

1 个答案:

答案 0 :(得分:0)

来自termios手册页的

 Another dependency is whether the O_NONBLOCK flag is set by open() or
 fcntl().  If the O_NONBLOCK flag is clear, then the read request is
 blocked until data is available or a signal has been received.  If the
 O_NONBLOCK flag is set, then the read request is completed, without
 blocking, in one of three ways:

       1.   If there is enough data available to satisfy the entire
            request, and the read completes successfully the number of
            bytes read is returned.

       2.   If there is not enough data available to satisfy the entire
            request, and the read completes successfully, having read as
            much data as possible, the number of bytes read is returned.

       3.   If there is no data available, the read returns -1, with errno
            set to EAGAIN.

你能检查一下是否是这种情况? 欢呼声。

编辑:OP将问题追溯到与pthreads的链接,导致读取功能被阻止。通过升级到OpenBSD> 5.2,通过将新的rthreads实现更改为openbsd上的默认线程库,解决了这个问题。有关guenther@ EuroBSD2012 slides

的更多信息