1

termios シリアル API 経由で使用する FTDI USB シリアル デバイスがあります。read() 呼び出しで (VTIME パラメータを使用して) 0.5 秒でタイムアウトするようにポートを設定しました。これは Linux でも FreeBSD でも機能します。ただし、OpenBSD 5.1 では、データが利用できない場合、read() 呼び出しは単純に永久にブロックされます (以下を参照)。read() は 500 ミリ秒後に 0 を返すと予想します。

少なくともタイムアウト機能に関して、termios API が OpenBSD で異なる動作をする理由を考えられる人はいますか?

編集: タイムアウトなしの問題は、pthread に対するリンクによって発生します。実際に pthread やミューテックスなどを使用しているかどうかに関係なく、単にそのライブラリにリンクすると、VTIME 設定に基づいてタイムアウトするのではなく、read() が永久にブロックされます。繰り返しますが、この問題は 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
  }
}
4

1 に答える 1

1

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 にアップグレードすることにより、この問題は、openbsd のデフォルトのスレッド ライブラリとして新しい rthreads 実装への変更によって解決されました。guenther@ EuroBSD2012 スライドの詳細

于 2013-04-12T13:16:01.810 に答える