ext3 파일 시스템의 일반 파일을 통해 통신하는 두 프로세스, 판독기와 기록기를 상상해 보십시오. Reader에는 IN_MODIFY
파일에 대한 모니터링이 있습니다. Writer는 한 번의 호출로 파일에 1000바이트를 씁니다 write()
. 리더는 inotify 이벤트를 받고 fstat
파일을 호출합니다. 독자는 무엇을 보는가?
st_size
독자가 자신의 문서에 대한 보상으로 최소 $1,000를 받을 수 있다는 것이 보장됩니까 ? 내 실험에 따르면 그렇지 않은 것 같습니다.Reader가 실제로 1000바이트를 읽을 수 있다는 보장이 있습니까
read()
?
이는 I/O 바인딩이 심한 상자에서 발생합니다. 예를 들어 sar
약 1초의 대기 시간이 표시됩니다. 내 경우에는 Reader가 실제로 inotify 이벤트를 받은 후 10초를 기다렸다가 호출했는데 stat
결과가 너무 작았습니다.
내가 원하는 것은 파일이 준비될 때까지 inotify 이벤트가 전달되지 않는다는 것입니다. 실제로 일어나는 일은 write()
Writer에서 호출하는 동안 inotify 이벤트가 발생하고 데이터가 준비된 한 시스템의 다른 프로세스에서 실제로 데이터를 사용할 수 있다는 것입니다. 이 경우 10초로는 충분하지 않습니다.
나는 커널이 실제로 내가 추측한 방식으로 inotify를 구현하는지 확인하기 위해 찾고 있는 것 같습니다. 또한 이 동작을 변경할 수 있는 옵션이 있습니까?
마지막으로, 이 동작을 고려할 때 inotify의 요점은 무엇입니까? 어떤 경우든 이벤트를 받은 후에는 데이터를 실제로 사용할 수 있을 때까지만 파일/디렉터리를 폴링할 수 있습니다. 이 작업을 계속하고 inotify를 잊어버릴 수도 있습니다.
***편집하다**** 글쎄요, 흔히 그렇듯이 제가 본 행동은 실제로 의미가 있었고 이제는 제가 실제로 무엇을 하고 있었는지 이해합니다. ^_^
실제로 파일이 있는 디렉터리의 IN_CREATE 이벤트에 응답하고 있습니다. 그래서 저는 실제로 파일 생성에 대한 응답으로 파일을 stat()하고 있습니다. IN_MODIFY 이벤트가 반드시 필요한 것은 아니지만 나중에 도착할 수도 있습니다.
IN_CREATE 이벤트가 수신되면 파일 자체의 IN_MODIFY를 구독하고 IN_MODIFY 이벤트가 수신될 때까지 실제로 파일을 읽으려고 시도하지 않도록 코드를 변경하겠습니다. 나는 거기에 작은 창이 있고 파일에 쓰기를 놓칠 수 있다는 것을 알고 있지만 최악의 경우 파일이 최대 시간(초) 후에 닫힐 것이기 때문에 이것은 내 응용 프로그램에 허용됩니다.
답변1
내가 보는 것에서커널 소스 코드, inotify는 쓰기가 완료된 후에만 시작됩니다(즉, 추측이 틀렸습니다). 알림이 트리거되면 sys_write
시스템 호출을 구현하는 함수에서 두 가지 일만 발생합니다 write
. 일부 스케줄러 매개변수가 설정되고 파일 설명자의 위치가 업데이트됩니다. 이 코드는2.6.14. 알림이 실행되면 파일의 크기가 이미 변경된 것입니다.
잘못될 수 있는 사항이 있는지 확인하세요.
- 아마도 독자는 이전에 작성된 오래된 공지를 받고 있을 것입니다.
- 독자가 전화를 걸고
stat
다시 전화read
하거나 그 반대의 경우, 그 사이에 어떤 일이 발생할 수 있습니다. 파일에 계속 추가하는 경우stat
먼저 호출하면 그 부분까지 읽을 수 있지만read
아직 inotify 알림을 받지 못했더라도 판독기가 호출될 때까지 더 많은 데이터가 기록되었을 수 있습니다. - 작성기가 호출되었다고 해서
write
커널이 요청한 문자 수만큼 쓸 것이라는 의미는 아닙니다. 원자 쓰기의 크기가 보장되는 경우는 거의 없습니다. 그러나 각write
호출은 원자성이 보장됩니다. 어느 시점에서는 데이터가 아직 기록되지 않았다가 갑자기 발생합니다.N바이트가 어디에 기록되었는지N호출의 반환 값입니다write
. 부분적으로 작성된 파일을 관찰하면write
반환된 파일이 해당 크기 매개변수보다 작다는 의미입니다.
무슨 일이 일어나고 있는지 조사하는 데 유용한 도구는 다음과 같습니다.
strace -tt
- 감사 하위 시스템