리눅스 시스템 프로그래밍 공부하는 초보인데요 파일과 스트림에 대해서 몇가지 질문이 있어요.
표준 I/O함수로(시스템 콜 함수인 write말고)로 입력한다고 하면요... 표준 입출력함수 호출 -> 버퍼링 -> 버퍼링 정책에 따라 버퍼에 일정량 량이 찼을 때(전체 버퍼링이면 버퍼 전체가 다 찼을 때, 줄 단위 버퍼링이면 새줄 문자가 입력되었을 때) -> write함수 호출 -> 커널 내부 버퍼에 저장 -> 대기열(큐)에 등록(sync함수, 데몬 프로세스가 30초마다 수행) -> 한가할 때 큐에 있는 내용이 디스크에 저장됨.
이런 과정인 거 맞나요??
유명한 책인 Advanced Programming the UNIX Environment의 번역본(류광님이 번역자세요)인 UNIX 고급 프로그래밍 제2판 이라는 책인데요.
3.13절(제3장은 파일 I/O)에 sync, fsync, fdatasync함수를 설명하면서 이런 설명을 하셨어요.
Unix System의 전통적인 구현들에서 대부분의 디스크 I/O 연산들은 커널 안의 버퍼 캐시 또는 페이지 캐시를 거친다. 프로세스가 파일에 자료를 기록하면, 보통의 경우 커널은 그 자료를 자신의 버퍼들 중 하나에 복사해서 내부적인 대기열(큐)에 등록해두고, 나중에 적당한 시점이 되면 디스크에 기록한다. 이런 방식을 지연된 쓰기(delayed write)라고 부른다.
지금은 5장(표준 I/O라이브러리)를 공부중인데요. 아무래도 3.13절의 설명과 관련이 있을텐데... 표준 I/O라이브러리 함수의 경우에는 파일을 열면 스트림도 같이 열린다고 하더라고요(그에 해당하는 버퍼도 때에 따라 생성).
근데 이 버퍼가 3.13절의 설명한 커널 내부 버퍼인지 아니면 다른 버퍼인지 궁금해서요... 두개다 설명이 맞다면 그리고 그 두 버퍼가 다른 거라면 아무래도 맨 위의 제 이해대로 표준 입출력이 이루어지지 않을까 생각하는데 이에 대해 설명 좀 부탁드리겠습니다.
stdio 의 FILE stream 은 사용자
stdio 의 FILE stream 은 사용자 버퍼입니다. setvbuf() 참고하세요.
답변 감사합니다...디스크 입출력에 대해서...
write함수나 기타 표준 입출력 함수나 다 메모리의 내용을 디스크에 저장한다는 점에서 같지요???
근데 함수 호출시에 디스크에 다 써질 때까지 기타렸다가 반환하는게 아니라 그냥 버퍼에만 저장해두고 반환하잖아요...
그 후에 대기열로 갔다가 큐 방식으로(First in First out) 기록된다는건데요. 커널이 한가할 때요...
근데 제가 궁금한 점은(질문에 대해 답에 대한 힌트를 찾을 만한 궁금증인듯하네요.) 바로 디스크에 저장이 안된다면, write로 파일에 쓰는 작업을 하는 프로그램을 돌린후, 바로 cat으로 보면 그 내용이 100% 있지 않습니까??? 그럼 이걸 어떻게 생각해야 될지 궁금합니다. 1. 프로세스가 끝나기 전까지 디스크(파일)에 기록이 되었다. 2. 디스크에 기록이 안되었을 수도 있으며 메모리 등에서 불러온다.
os 커널의 버퍼를 말씀하시는 거라면, 파일에 쓰여질
os 커널의 버퍼를 말씀하시는 거라면,
파일에 쓰여질 데이타 뿐만 아니라 그 파일에 대한 메타 정보 역시 디스크에 쓰여지기 전일 수도 있습니다.
cat 뿐만 아니라 ls -l 에서 보여지는 정보도 메모리에 아직 대기 중인 것이 보여질 수 있다는 뜻입니다.
power fail 때 파일 뿐만 아니라 파일 시스템 자체가 깨질 수 있다는 것을 들어보셨을텐데요.
메모리에서 불러온다는 말씀이시군요...
디스크에는 아직 기록되기 전일 가능성이 높군요... 답변 감사합니다. 궁금증이 해소가 되었습니다...^^
3.13절과 5장에서 말하는 버퍼는 다른 걸
3.13절과 5장에서 말하는 버퍼는 다른 걸 지칭합니다. 대략적으로 처음 글에서 이해한 내용대로 이루어지는게 맞습니다.
그렇군요 답변 감사합니다.
결국 표준 I/O함수도 내부에서 시스템콜함수를 호출할테니 결국 3.13절의 과정이 디스크 기록 연산에서는 반드시 일어난다고 볼 수 있겠군요... 답변 감사합니다...^^
댓글 달기