Programing

읽기() 함수 호출의 시간 초과를 구현하는 방법?

c10106 2022. 5. 4. 19:09
반응형

읽기() 함수 호출의 시간 초과를 구현하는 방법?

시리얼 com 포트를 통신에 사용하고, read() 함수를 호출할 때마다 타임아웃을 구현하고 싶다.

int filedesc = open( "dev/ttyS0", O_RDWR );

read( filedesc, buff, len );

편집:

나는 리눅스 OS를 사용하고 있다.선택 기능 호출을 사용하여 구현하는 방법

selectroperties는 가장 높은 파일 설명자 + 1인 5개의 매개 변수를 사용하고, 그 다음 fd_set를 읽으려면 1개, 쓰기용 1개, 예외용 1개를 사용한다.마지막 파라미터는 구조체 시간 값이며, 시간 초과에 사용된다.오류 시 -1, 시간 초과 시 0 또는 설정된 세트의 파일 설명자 수를 반환한다.

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>

int main(void)
{
  fd_set set;
  struct timeval timeout;
  int rv;
  char buff[100];
  int len = 100;
  int filedesc = open( "dev/ttyS0", O_RDWR );

  FD_ZERO(&set); /* clear the set */
  FD_SET(filedesc, &set); /* add our file descriptor to the set */

  timeout.tv_sec = 0;
  timeout.tv_usec = 10000;

  rv = select(filedesc + 1, &set, NULL, NULL, &timeout);
  if(rv == -1)
    perror("select"); /* an error accured */
  else if(rv == 0)
    printf("timeout"); /* a timeout occured */
  else
    read( filedesc, buff, len ); /* there was data to read */
  close(filedesc);
}

의 대안으로select(), 직렬 포트(직렬 포트)의 특정 경우에 사용할 수 있음tcsetattr()읽기 시간 제한과 함께 파일 설명자를 비논리적 모드로 전환한다.

이렇게 하려면 설정을 해제하십시오.ICANON플래그를 지정하고VTIME제어 문자:

struct termios termios;

tcgetattr(filedesc, &termios);
termios.c_lflag &= ~ICANON; /* Set non-canonical mode */
termios.c_cc[VTIME] = 100; /* Set timeout of 10.0 seconds */
tcsetattr(filedesc, TCSANOW, &termios);

참고VTIME10분의 1초 단위로 측정되며, 이에 사용되는 유형은 일반적으로unsigned char, 즉, 최대 제한 시간은 25.5초입니다.

소켓을 비차단 모드에서 작동하도록 설정한 경우, 각 통화는 현재 사용 가능한 데이터(있는 경우)만 읽는다.그래서 이것은 사실상 즉각적인 타임아웃과 같다.

다음과 같은 기능을 가진 소켓에 비차단 모드를 설정할 수 있다.

int setnonblock(int sock) {
   int flags;
   flags = fcntl(sock, F_GETFL, 0);
   if (-1 == flags)
      return -1;
   return fcntl(sock, F_SETFL, flags | O_NONBLOCK);
}

(차단되지 않은 소켓에서 읽는 방법에 대한 자세한 내용은read맨 페이지)

아래 코드는 문자당 밀리세컨드 타임아웃을 사용한다.나는 그것을 COM 포트에서 읽을 때 내 프로젝트 중 하나에 사용한다.

size_t TimeoutRead (int port, void*buf, size_t size, int mlsec_timeout)
{
    struct pollfd fd = { .fd = port, .events = POLLIN };

    size_t      bytesread = 0;

    while (poll (&fd, 1, mlsec_timeout) == 1)
    {
        int chunksize = read (port, buf + bytesread, size);
        if (chunksize == -1)
            return -1;

        bytesread += chunksize;
        size -= chunksize;

        if (size == 0)
            return bytesread;
    }

    // TODO: IsTimeout = true;
    return bytesread;
}

OS가 무엇인지 말하지 않지만 Linux에서 실행 중인 경우 선택 호출을 사용할 수 있다.파일 설명자에 읽을 내용이 있으면 반환하거나 읽을 내용이 없으면 시간 초과되도록 설정할 수 있다.반환 코드는 어느 것을 표시하는지 표시한다.

참조URL: https://stackoverflow.com/questions/2917881/how-to-implement-a-timeout-in-read-function-call

반응형