2010-01-11 6 views
0

저는 현재 C++ 프로그램에서 SIGIO 관련 문제를 겪고 있습니다.Linux : 다중 SIGIO 문제 (비동기 직렬 통신)

  • 플랫폼 : 리눅스 2.6.30, 86 아치
  • 시나리오 : 비동기 시리얼 통신.

나는 리눅스 직렬 프로그래밍 하우투 (Linux Serial Programming HowTo)에서 this async-communication example을 따라 왔으며 완벽하게 작동했습니다.

그런 다음 "sleep + check wait_flag"것을 제거하고 이제 signal_handler_IO()에서 read() 부분을 직접 처리합니다. 즉, 일부 입력을 사용할 수 있으면 신호 처리기가 호출되고 직렬 포트 (*)에서 강제로 읽습니다.

내 코드가 작동하는 것 같지만 불행히도 새로운 입력을 사용할 수있는 경우 SIGIO 신호가 여러 번 발생하여 가짜/불완전 읽기 (각 SIGIO가 강제로 읽음을 받음)가 발생합니다.

읽기 버퍼를 제어하는 ​​일련의 옵션 (예 : VMIN = 255/VTIME = 15, VMIN = 50/VTIME = 0, ...)이 변경되었습니다. SA_SIGINFO 플래그를 설정하려고 시도했지만 성공하지는 못했습니다.

그래서 : 내가 처리/SIGIO 모금에 대해 실종 무엇

  • ?
  • 이 "SIGIO storm"을 피할 수있는 방법이 있습니까?
  • SIGIO 상승 정책을 제어 할 수있는 방법이 있습니까?

미리 감사드립니다.

안녕히 계십시오.

(*) : 실제로 나는 신호 처리기가 모든 직렬 처리 물건을 캡슐화하는 객체의 멤버 함수를 호출하기 때문에 this C++ FAQ Lite hint을 따르고 있습니다. 불행히도 문제는 여전히 발생한다. 시그널 핸들러 자체에서 read()를 호출한다.

답변

4

신호 처리기에서 read으로 전화 하시겠습니까? 이것은 나쁘다. 거의 기능이 없습니다 async-signal safe입니다. SIGIO 폭풍은 SIGIO를 재귀 적으로 보내는 읽기로 인해 발생할 수 있습니다. 신호 처리기는 플래그를 설정하고 즉시 반환해야합니다.

+0

아니요, C++ FAQ Lite에서 제안한 것처럼 신호 처리기는 실제 read()를 수행하는 비 정적 객체의 멤버 함수를 호출합니다. 어쨌든 간단한 해결책을 발견했습니다 : 읽기 바이트에 대해 (thread-safe 액세스로) 버퍼를 추가했습니다. 시그널 핸들러가 호출 될 때마다 직렬 포트에서 read()를 수행하고 읽기 바이트가 버퍼에 추가됩니다. 그런 다음 "SIGIO storm"문제가 해결되었습니다. 필요할 때 버퍼를 읽음으로써 필요한 것을 추출 할 수 있기 때문입니다. 추신 : 귀하의 회신에 감사드립니다. –

+0

나는 길을 찾은 것을 기쁘게 생각합니다. 신호 안전성에 대한 요점을 명확히하기 위해서 : 회원 함수를 호출하는 것은 중요하지 않습니다. 스택의 상단은 여전히 ​​시그널 핸들러였다. – Tobu

+1

신호 처리 컨텍스트에서 read()를 호출 할 수 없습니다. 즉, 신호 처리기는 read()를 호출 할 수 없으며 신호 처리기에서 호출 할 수 없습니다. –