fork() 뒤에 있는 'file descriptor'에 대한 간단한 설명 찾기
"유닉스 환경에서의 고급 프로그래밍"에서, 두 번째 판, By W. Richard Stevens.섹션 8.3 포크 기능.
설명은 다음과 같습니다.
부모와 자식이 동일한 파일 오프셋을 공유하는 것이 중요합니다.
자식에게 포크를 씌운 다음 자식이 완료될 때까지 기다리는 프로세스를 고려합니다.두 공정 모두 정상 처리의 일부로 표준 출력에 쓴다고 가정합니다.부모의 표준 출력이 셸에 의해 리디렉션된 경우 자녀가 표준 출력에 쓸 때 부모의 파일 오프셋을 자식이 업데이트해야 합니다.
내 답변:
{1} 부모의 std 출력이 예를 들어 'file1'로 리디렉션되는 경우 자식이 쓴 후 무엇을 업데이트해야 합니까?부모의 원래 표준 출력 오프셋 또는 리디렉션 출력(즉, file1) 오프셋?나중일 수는 없지, 그렇죠?
{2} 업데이트는 어떻게 수행됩니까?자녀에 의해 명시적으로, OS에 의해 암묵적으로, 파일 설명자 자체에 의해?포크 이후, 저는 부모와 자녀가 각자의 길을 가고 그들만의 파일 설명자 복사본을 가지고 있다고 생각했습니다.그러면 자식 업데이트가 부모 측에 어떻게 오프셋을 제공합니까?
이 경우 부모가 기다리는 동안 자녀는 표준 출력에 쓸 수 있습니다. 자녀가 완료되면 부모는 자녀가 작성한 내용에 출력이 추가된다는 것을 알고 계속해서 표준 출력에 쓸 수 있습니다.부모와 자식이 동일한 파일 오프셋을 공유하지 않으면 이러한 유형의 상호 작용을 수행하기가 더 어려워지고 부모의 명시적인 작업이 필요합니다.
부모와 자식이 모두 동일한 설명자에 쓰는 경우 부모가 자식을 기다리게 하는 등의 동기화 형식 없이 출력이 혼합됩니다(포크 이전에 열려 있던 설명자라고 가정).이것은 가능하지만 정상적인 작동 모드는 아닙니다.
포크 뒤에 설명자를 처리하는 데는 두 가지 일반적인 경우가 있습니다.
부모는 자식이 완료될 때까지 기다립니다.이 경우 부모는 설명자를 사용하여 아무것도 할 필요가 없습니다.자식이 종료되면 자식이 읽거나 쓴 공유 설명자는 그에 따라 파일 오프셋이 업데이트됩니다.
부모와 아이 모두 각자의 길을 갑니다.여기서, 포크 다음에, 부모는 필요 없는 설명자들을 닫고, 아이는 같은 일을 합니다.이렇게 하면 어느 쪽도 다른 쪽의 열린 설명자를 방해하지 않습니다.이 시나리오는 종종 네트워크 서버의 경우에 해당합니다.
내 응답:
{3} fork()가 실행되면 자식이 부모가 가지고 있는 것, 이 경우 파일 설명자의 사본을 받고 수행하는 것으로 이해할 수 있습니다.상위 및 하위가 공유하는 파일 설명자에 대한 오프셋이 변경되는 경우 설명자가 오프셋 자체를 기억하기 때문일 수 있습니다.내 말이 맞니?
저는 개념이 좀 생소합니다.
프로세스가 읽기 및 쓰기 호출에서 파일을 식별하는 데 사용하는 작은 정수인 파일 설명자와 커널의 구조인 파일 설명을 구별하는 것이 중요합니다.파일 오프셋은 파일 설명의 일부입니다.그것은 알맹이 속에 삽니다.
예를 들어 이 프로그램을 사용해 보겠습니다.
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
int main(void)
{
int fd;
fd = open("output", O_CREAT|O_TRUNC|O_WRONLY, 0666);
if(!fork()) {
/* child */
write(fd, "hello ", 6);
_exit(0);
} else {
/* parent */
int status;
wait(&status);
write(fd, "world\n", 6);
}
}
(모든오류확인이누락되었습니다)
우리가 이 프로그램을 컴파일하면, 그것을 부릅니다.hello
다음과 같이 실행합니다.
./hello
다음과 같은 일이 발생합니다.
은 프램이열다니를 .output
파일(이미 존재하지 않는 경우)을 만들거나 크기가 0인 경우 파일을 잘라냅니다.. (은 "" 은널설리만다듭니을이명은것커파서커에널눅스일리▁a(▁the"입니다.)struct file
프로세스의 테이블에서 이 아닌 와 및 호출 프로세스의 파일 설명자(해당 프로세스의 파일 설명자 테이블에서 아직 사용되지 않는 음이 아닌 최소 정수)와 연결합니다. 설명자에 됩니다.fd
을 위해서라고 해 보세요.fd
3입니다.
프로그램이 포크()를 수행합니다.새 자식 프로세스는 부모 파일 설명자 테이블의 복사본을 가져오지만 파일 설명은 복사되지 않습니다.두 프로세스의 파일 테이블에 있는 항목 3번은 동일함을 가리킵니다.struct file
.
상위 프로세스는 하위 프로세스가 쓰는 동안 대기합니다.아이의 글은 전반부의 원인이 됩니다."hello world\n"
파일에 저장하고 파일 오프셋을 6만큼 앞당깁니다.은 파오프다있습다니에 .struct file
!
이는고나는,.wait()
된 fd3를하여 쓰기를 수행합니다. fd3 파일 오프셋은 .fd3 파일 오프셋입니다.write()
따라서 메시지의 두 번째 절반은 첫 번째 부분 이후에 저장되며, 파일 설명이 공유되지 않은 경우와 마찬가지로 상위 파일 오프셋이 0인 경우처럼 덮어쓰지 않습니다.
은 "" "" "" " ""를 합니다.struct file
더 이상 사용하지 않고 해제합니다.
책의 같은 섹션에는 파일을 열었을 때 있는 세 개의 테이블을 보여주는 다이어그램이 있습니다.
사용자 파일 설명자 테이블(프로세스 테이블 항목의 일부), 파일 테이블 및 inode 테이블(v-node 테이블).이제 파일 설명자(파일 설명자 테이블에 대한 인덱스) 항목이 파일 테이블 항목을 가리키고, 이 항목은 노드 테이블 항목을 가리킵니다.
이제 파일 오프셋(다음 읽기/쓰기가 발생하는 위치)이 파일 테이블에 있습니다.
부모에서 파일이 열려 있다고 가정하면 설명자, 파일 테이블 항목 및 아이노드 참조도 있습니다.
이제 자식을 만들 때 자식에 대한 파일 설명자 테이블이 복사됩니다.따라서 파일 테이블 항목(열린 설명자에 대한)의 참조 수가 증가합니다. 즉, 동일한 파일 테이블 항목에 대한 참조가 두 개 있습니다.
이제 이 설명자는 동일한 파일 테이블 항목을 가리키며 상위 및 하위 모두에서 사용할 수 있으므로 오프셋을 공유합니다.이 배경을 통해 여러분의 질문을 확인해 보겠습니다.
- 부모의 std 출력이 예를 들어 'file1'로 리디렉션되는 경우 자녀가 쓴 후 자녀가 업데이트해야 할 내용은 무엇입니까?부모의 원래 표준 출력 오프셋 또는 리디렉션 출력(즉, file1) 오프셋?나중일 수는 없죠?]
자식은 명시적으로 아무것도 업데이트할 필요가 없습니다.그 책의 작가는 노력하고 있습니다.
부모의 표준 출력이 파일로 리디렉션되고 포크 호출이 이루어진다고 가정합니다.그 후에 부모님이 기다리고 있습니다.이제 설명자가 중복됩니다. 즉, 파일 오프셋도 공유됩니다.이제 아이가 표준화할 내용을 쓸 때마다 기록된 데이터가 리디렉션 파일에 저장됩니다.오프셋은 쓰기 호출에 의해 자동으로 증가합니다.
이제 아이가 나간다고 해요.그래서 부모님은 기다리다가 나와서 표준에 뭔가를 적습니다(방향 변경됨).이제 부모의 쓰기 호출 출력이 자녀가 작성한 데이터 뒤에 -> 배치됩니다.자식이 글을 쓴 후 오프셋의 현재 값이 변경되었기 때문에 -> 이유.
Parent ( )
{
open a file for writing, that is get the
descriptor( say fd);
close(1);//Closing stdout
dup(fd); //Now writing to stdout means writing to the file
close(fd)
//Create a child that is do a fork call.
ret = fork();
if ( 0 == ret )
{
write(1, "Child", strlen("Child");
exit ..
}
wait(); //Parent waits till child exit.
write(1, "Parent", strlen("Parent");
exit ..
}
위의 유사 코드를 참조하십시오. 열린 파일에 포함된 최종 데이터는 ChildParent가 됩니다.자식이 글을 썼을 때 파일 오프셋이 변경된 것을 볼 수 있습니다. 부모의 쓰기 호출에서 파일 오프셋을 사용할 수 있습니다. 왜냐하면 축제가 공유되기 때문입니다.
2. 업데이트는 어떻게 이루어집니까?자녀에 의해 명시적으로, OS에 의해 암묵적으로, 파일 설명자 자체에 의해?포크 이후, 저는 부모와 자녀가 각자의 길을 가고 그들만의 파일 설명자 사본을 가지고 있다고 생각했습니다.그러면 부모 측에 대한 자식 업데이트 오프셋은 어떻게 됩니까?]
Now I think the answer is clear-> by the system call that is by the OS.
[3. 포크()가 실행되면, 제가 이해하는 것은 아이가 부모가 가지고 있는 것의 사본을 받고, 이 경우에는 파일 설명자를 가지고, 그 일을 한다는 것입니다.상위 및 하위가 공유하는 파일 설명자에 대한 오프셋이 변경되는 경우 설명자가 오프셋 자체를 기억하기 때문일 수 있습니다.제 말이 맞나요?]
이것 또한 분명해야 합니다.사용자 파일 테이블의 항목은 오프셋을 포함하는 파일 테이블 항목을 가리킵니다.
즉, 시스템 호출은 설명자로부터 오프셋을 가져올 수 있습니다.
언급URL : https://stackoverflow.com/questions/11733481/seeking-a-simple-description-regarding-file-descriptor-after-fork
'programing' 카테고리의 다른 글
모든 콘솔 메시지에 타임스탬프 추가 (0) | 2023.08.14 |
---|---|
Oracle 클라이언트 및 네트워킹 구성 요소를 찾을 수 없습니다. (0) | 2023.08.14 |
스프링 부트 - 다중 파트 파일 최대 업로드 크기 예외 (0) | 2023.08.14 |
CheckChanged에서 트리거하지 않고 CheckChanged 값 변경 (0) | 2023.08.14 |
Ajax 성공 후 페이지 다시 로드 (0) | 2023.08.14 |