시리얼통신 프로그래밍중에 약간의 문제가~~
시리얼버퍼에서 데이터를 read()함수로 읽어내는데...
저는 read()함수가 시리얼버퍼에 데이터가 들어올 때까지 기다리고있는것으로 알고있었는데요~!~
그렇지가 않아서요...그냥 리턴해버리고마네요~~
원래 그런건지???
부탁드립니다~~
RETURN VALUE
On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. It is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal), or because read() was interrupted by a signal. On error, -1 is returned, and errno is set appropriately. In this case it is left unspecified whether the file position (if any) changes.
ERRORS
EINTR The call was interrupted by a signal before any data was read.
EAGAIN Non-blocking I/O has been selected using O_NONBLOCK and no data was immediately available for reading.
EIO I/O error. This will happen for example when the process is in a background process group, tries to read from its controlling tty, and either it is ignoring or blocking SIGTTIN or its process group is orphaned. It may also occur when there is a low-level I/O error while reading from a disk or tape.
EISDIR fd refers to a directory.
EBADF fd is not a valid file descriptor or is not open for reading.
EINVAL fd is attached to an object which is unsuitable for reading.
EFAULT buf is outside your accessible address space.
ERESTARTSYS read is interrupted by a trace.
이 중에서 EAGAIN은 O_NONBLOCK으로 open된 fd에 대하여 해당 시점에 읽기 가능한 데이터가 없으면 에러를 리턴하네요.
시리얼 통신은 잘 모르지만 해당 fd의 open mode나 ioctl 문 등을 점검해서,
해당 fd가 non blocking모드는 아닌지 확인해보시기 바랍니다.
errno 값은 시스템 API의 일부이기 때문에, errno를 믿지 못하겠다는 말은 시스템을 믿을 수 없다는 말과 똑같습니다.
POSIX thread를 지원하는 시스템이라면 errno도 전부 쓰레드 별로 따로 생성하기 때문에 서로의 간섭은 전혀 걱정할 필요가 없습니다. Signal handler를 부주의하게 짜서 그 안에서 errno를 바꿔버리는 케이스가 아니라면, 시스템 라이브러리 함수를 부른 이후 errno 값을 읽었는데 잘못된 값이 나오는 경우는 없습니다. 있으면 OS나 시스템 라이브러리의 버그입니다.
read () 함수 리턴
read 함수의 리턴
On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. It is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal), or because read() was interrupted by a signal. On error, -1 is returned, and errno is set appropriately. In this case it is left unspecified whether the file position (if any) changes.
ERRORS
EINTR The call was interrupted by a signal before any data was read.
EAGAIN Non-blocking I/O has been selected using O_NONBLOCK and no data was immediately available for reading.
EIO I/O error. This will happen for example when the process is in a background process group, tries to read from its controlling tty, and either it is ignoring or blocking SIGTTIN or its process group is orphaned. It may also occur when there is a low-level I/O error while reading from a disk or tape.
EISDIR fd refers to a directory.
EBADF fd is not a valid file descriptor or is not open for reading.
EINVAL fd is attached to an object which is unsuitable for reading.
EFAULT buf is outside your accessible address space.
ERESTARTSYS read is interrupted by a trace.
이 중에서 EAGAIN은 O_NONBLOCK으로 open된 fd에 대하여 해당 시점에 읽기 가능한 데이터가 없으면 에러를 리턴하네요.
시리얼 통신은 잘 모르지만 해당 fd의 open mode나 ioctl 문 등을 점검해서,
해당 fd가 non blocking모드는 아닌지 확인해보시기 바랍니다.
답변
답변 고맙네요~~
그런데 말이죠~ 저는 정확히 tty를 블록 모드로 열었거든요~~
저도 nonblock모드로 되어있지 않나 해서 보았었는데~~
끝내 해결하지 못하고 폴링을 쓰고말았어요~~
하여튼간에 답변 주셔서 고마워요~~
앞으로도 잘 부탁드립니다~
좋은 하루 되세요!!
APUE
APUE 좀 볼것을 권고합니다.
시그널 들어오면 다
시그널 들어오면 다 읽지 않아도 튕겨나갑니다.
이때 errno에는 EINTR이 들어가 있죠. read() 리턴값은 읽어들인 양입니다.
Written By the Black Knight of Destruction
Written By the Black Knight of Destruction
요건 관련 없는거 하나..
errno의 경우 신뢰성이 생각보다 떨어진다는 글을 읽었습니다..
문제는 errno 값에 접근하는 많은 함수들이 있다는 것이죠...
errno의 원자성이 확실히 보장된다는 말을 찾지 못했네요..
그럴 리가요......
errno 값은 시스템 API의 일부이기 때문에, errno를 믿지 못하겠다는 말은 시스템을 믿을 수 없다는 말과 똑같습니다.
POSIX thread를 지원하는 시스템이라면 errno도 전부 쓰레드 별로 따로 생성하기 때문에 서로의 간섭은 전혀 걱정할 필요가 없습니다. Signal handler를 부주의하게 짜서 그 안에서 errno를 바꿔버리는 케이스가 아니라면, 시스템 라이브러리 함수를 부른 이후 errno 값을 읽었는데 잘못된 값이 나오는 경우는 없습니다. 있으면 OS나 시스템 라이브러리의 버그입니다.
errno는
errno는 thread-safe 하지 않습니다.
따라서,
쓰레드1: read 에러 발생하여 errno를 세팅
쓰레드2: read 성공
쓰레드1: errno 체크
위와 같은 상황이라면, errno는 믿을만한 구석이 없지요.
OS나 라이브러리 버그 아니더라도,
멀티 쓰레드 환경에서는 errno 믿고 프로그램 짜시면 낭패봅니다.
저도 과거의 기록이 새록새록 ㅠㅠ
으흐 자답입니다. jick님 말씀이 맞네요.
혹시나 해서 문서 찾아봤더니,
요즘 errno는 Thread-safe하네요. ㅠㅠ
jick님 말씀이 맞습니다 ^^
컴파일할때 옵션
컴파일할때 옵션 줘야 합니다.
-D_REENTRANT였던가로 기억합니다.
Written By the Black Knight of Destruction
Written By the Black Knight of Destruction
Oh~~ I C,,,
컴파일할 때 옵션주는것도 있었군요~~
여러가지로 고맙네요~~고수님들...
앞으로도 잘 부탁드립니다...
좋은 하루 되세요!!
여러 고수님들 답변
여러 고수님들 답변 고맙네요~~
앞으로도 잘 부탁드립니다~~~
좋은 하루 되세요!!
댓글 달기