printf가 비동기 신호 안전 기능이 아닌 이유는 무엇입니까?

printf가 비동기 신호 안전 기능이 아닌 이유는 무엇입니까?

우리는 이것이 printf비동기식 신호 안전 기능이 아니라는 것을 알고 있습니다. 다음은 나의 기본적인 이해입니다.

printfin 메소드를 호출하여 main내용이 stdio 버퍼에 기록되었다고 가정하면, 버퍼가 파일에 플러시되기 직전에 신호가 도착하고 신호 처리기도 호출됩니다 printf. 두 번째 처리기는 printf해당 내용을 버퍼에 추가하고 이제 buffer 첫 번째 호출과 두 번째 호출의 내용이 일치하지 않아 잘못된 것이므로 신호 처리기에서 비동기가 아닌 안전 함수를 사용할 수 없습니다. 내 이해가 맞나요?

내 이해가 정확하다면 비동기 안전 기능이 이 문제를 어떻게 해결합니까? 안전한 함수는 여전히 호출에 대한 귀중한 버퍼 데이터를 포함할 수 있는 버퍼를 처리해야 하기 때문에?

답변1

printf설명했듯이 동기화 없이 전역 상태를 조작하게 되므로 비동기 신호가 안전합니다. 재미를 더하기 위해 재진입이 필요하지 않습니다. 귀하의 예에서 신호는 printf첫 번째 런타임에 의해 처리될 수 있지만 두 번째 신호는 printf첫 번째 호출의 상태를 망칠 수 있습니다.

비동기 신호를 안전하게 사용하기 위해 권장되는 방법은 신호 처리기가 어딘가에 플래그를 설정하고 기본 프로그램 흐름이 플래그를 처리하도록 하는 것입니다. 이는 재진입, 직렬화된 출력 문제를 방지하고 신호 처리기를 빠르게 유지하는 데 도움이 됩니다.

답변2

내 이해가 맞나요?

최대. 버퍼 오프셋과 크기를 조정할 때 중첩된 printf 호출이 서로 겹쳐서 데이터가 일관되지 않을 뿐만 아니라 충돌이 발생할 수도 있다는 문제도 있습니다.

비동기 안전 기능은 이 문제를 어떻게 해결합니까?

두 종류가 있습니다비동기 신호 안전 기능:

  • strlen(3)과 같은 재진입 함수는 지역 변수, 매개변수 및 반환 값을 보유하는 데 사용되는 메모리를 제외한 어떤 메모리도 수정하지 않습니다.

  • 함수는 kill(2), waitpid(2) 등과 같은 간단한 시스템 호출 래퍼입니다. 위에서 언급한 것처럼 userland 부분은 완전히 재진입 가능하지만 커널 부분의 경우 커널이 모든 것을 처리합니다.

관련 정보