나는 경험이 많지 않고 사용자 수준에서 하드웨어에 이르기까지 어떻게 해석되는지에 참여하려고 노력합니다.
따라서 명령이 셸에서 트리거되면 fork()
해당 하위 프로세스가 상속되어 exec()
메모리에 로드되어 실행됩니다.
- 하위 프로세스에 상위 프로세스(즉, 원본 프로세스)의 모든 속성이 포함되어 있는 경우 하위 프로세스에는 또 무엇이 필요합니까? 원래 프로세스가 메모리에 로드되었을 수도 있습니다.
- 이 개념이 UNIX의 모든 실행 프로그램에
fork
적용 됩니까?exec
또한 쉘 스크립트를 좋아합니까, 아니면 단지 명령을 좋아합니까? 쉘 내장에서도 작동합니까? - 때이다쓰기 중 복사명령/스크립트를 실행하려면 어떤 개념이 사용됩니까?
한꺼번에 너무 많은 질문을 드려 죄송하지만, 어떤 명령 실행을 생각하면 이런 질문들이 바로 떠오릅니다.
답변1
따라서 쉘에서 명령이 실행되면 fork()는 하위 프로세스를 상속하고 exec()는 하위 프로세스를 메모리에 로드하여 실행합니다.
완전한 것은 아니고. fork()
현재 프로세스를 복제하고 동일한 하위 프로세스를 만듭니다. exec()
새로 로드하다프로그램현재 프로세스를 입력하고 기존 프로세스를 교체합니다.
내 질문은 다음과 같습니다
상위 프로세스(즉, 원래 프로세스)의 모든 속성을 포함하는 경우 하위 프로세스에는 무엇이 필요합니까? 원래 프로세스가 메모리에 로드되었을 수도 있습니다.
부모 프로세스가 아직 종료되기를 원하지 않기 때문에 필요합니다. 새로운 프로세스를 시작하고 계속하면서 뭔가를 하려고 합니다.
이러한 포크 및 exec 개념이 UNIX의 모든 실행 프로그램에 적용됩니까? 쉘 스크립트와 같습니까, 아니면 명령에만 해당됩니까? 쉘 내장에서도 작동합니까?
외부 명령의 경우 셸은 fork()
해당 명령이 새 프로세스에서 실행되도록 작업을 수행합니다. 내장 함수는 쉘에 의해서만 직접 실행됩니다. 주목할만한 또 다른 명령은 쉘을 exec
먼저 호출하지 않고 exec()
외부 프로그램 에 명령한다는 것입니다 fork()
. 이는 쉘 자체가 새로운 프로그램으로 대체되어 프로그램이 반환되지 않고 종료된다는 것을 의미합니다. exec true
라고 말하면 /bin/true
쉘이 교체되고 즉시 종료되며 터미널에서 더 이상 아무것도 실행되지 않으므로 닫힙니다.
쓰기 중 복사 개념을 사용할 때 명령/스크립트를 실행합니까?
석기 시대에는 fork()
호출 프로세스의 모든 메모리를 새 프로세스에 복사해야 했습니다. 기록 중 복사는 두 프로세스가 모두 동일한 메모리를 공유하기 시작하고 두 프로세스에서 쓴 페이지가 필요할 때만 복사되도록 페이지 테이블을 설정하는 최적화입니다.
답변2
- 일부 프로그램의 경우 하위 프로세스는 한 가지 작업(직렬 포트에서 읽기, 터미널에 쓰기)을 수행하고 상위 프로세스는 계속해서 다른 작업(터미널에서 읽기, 직렬 포트에 쓰기)을 수행합니다. 또 다른 전형적인 예는 발생하는 장기 실행 계산에 대해 체크포인트를 수행하는 하위 프로세스입니다. 대부분의 경우 하위 프로세스는 디렉터리 변경, 신호 처리기 재설정, 파일 설명자 재설정과 같은 일부 설정을 수행한 다음
execve()
다른 코드로 자신을 덮어쓰도록 호출합니다. fork()
그리고exec()
이는 모든 실행 파일에 적용됩니다. 실제로 argc 및 argv, 파이프, 포크 및 exec와 함께 이것이 Unix를 다른 운영 체제와 구별하는 요소입니다. BSD , Plan 9 및 Linuxfork()
와 같은 일부 전문화 또는 일반화가 있지만 원칙은 동일하게 유지됩니다.vfork()
rfork()
clone()
- 기록 중 복사는 실제로 사용자에게 표시되지 않으며 하위 프로세스 생성 및 실행을 최적화하는 기술에 가깝습니다. 호출 스택과 힙(할당된 메모리
malloc()
및 심지어 정적 또는 전역 범위 변수 포함)은 "기록 중 복사"일 수 있습니다. 호출을 통해 하위 프로세스가 생성되면fork()
커널은 하위 프로세스가 상위 프로세스와 정확히 동일한 메모리 페이지(힙 및 스택)를 갖도록 설정합니다. 하드웨어(메모리 관리 장치)가 힙 또는 스택에 대한 쓰기를 감지하면 커널은 새 물리적 메모리 페이지를 가져오고 상위 프로세스의 페이지를 새 페이지에 복사한 다음 해당 새 페이지를 하위 프로세스의 스택 또는 힙에 매핑합니다. . 이는 커널이 하위 프로세스의 스택과 힙을 완전히 복사하는 것보다 페이지 매핑을 설정하는 데 더 적은 시간을 소비하기 때문에 최적화를 구성합니다.
답변3
하위 프로세스에 상위 프로세스(즉, 원본 프로세스)의 모든 속성이 포함되어 있는 경우 하위 프로세스에는 또 무엇이 필요합니까? 원래 프로세스가 메모리에 로드되었을 수도 있습니다.
이 질문에 대한 답은 엄격한 메모리 제약 하에서 작동해야 하고 메모리/주소 공간에서 한 번에 하나의 실행 프로세스만 있었던 초기 Unix 구현을 보면 알 수 있습니다.
멀티태스킹은 한 프로세스를 디스크로 교체하고 다른 프로세스를 교체하여 수행됩니다.
이제 fork
시스템 호출은 거의 동일합니다. 하나의 프로세스를 디스크로 교체하지만 다른 프로세스를 교체하는 대신 메모리 내 복사본에 다른 프로세스 ID를 제공하고 이를 반환합니다. exec
결국 지금은 프로세스가 다른 실행 파일을 입력하기로 결정하는 적절한 시기입니다.
fork
+ exec
따라서 빌드 프로세스에는 실제로 눈에 띄는 오버헤드가 없습니다. 어쨌든 프로세스를 디스크로 교체해야 하며, 어쨌든 이전 프로세스 이미지는 사용 가능한 메모리 위치에 있습니다.
사용 가능한 메모리 및 메모리 관리 장치의 수가 증가하고 여러 메모리 프로세스가 증가함에 따라 초기에 무시할 수 있었던 분기 비용이 일부 아키텍처에서는 더욱 골치 아픈 문제가 되었습니다. 이렇게 vfork
탄생했습니다.
답변4
이것을 가능한 한 쉽게 이해하기 위해 비유를 사용하겠습니다. 파이를 굽자!
우리는 요리 책을 집어들고 읽기 시작했고, 수제 크러스트가 있는 딸기 대황 파이(내가 가장 좋아하는 것)를 결정했습니다. 계란과 과일 빼고는 필요한 거의 모든 것이 부엌에 있었지만, 우리는 농장에 살았고 과일도 제철이었기 때문에 문제가 되지 않았습니다. 문제는 오븐이 고장나서 모든 것을 할 시간이 부족하다는 것이었습니다. 내가 한 명 이상 있으면 좋지 않을까요?
fork()가 구출됩니다. 나는 지금 두 명이다. 우리 둘 다 부엌으로 가서 파이 크러스트를 만들기 시작했습니다. 이런. 그럼 포크로부터의 반환을 살펴보겠습니다. 나는 큰 숫자를 얻었고 그는 0을 얻었습니다. 그래서 나는 부엌으로 갔고 그는 닭장과 정원으로갔습니다. 오븐을 통과할 때 다시 fork()하고 반환 값을 살펴봅니다. 앗, 0이 나왔습니다. 내가 깨진 오븐을 바라보는 동안 그는 계속해서 밀가루를 먹었다. 문을 열었는데 빛이 없어 문을 닫았습니다. 오븐 수리하는 방법 아는 사람 있나요?
exec()가 구조에 옵니다. 공구 벨트에 있는 전압계에 손을 뻗으면 전구가 진단을 수행하여 전원을 확인했고 차단기가 작동하여 쉽게 고칠 수 있었습니다. 회로 차단기 패널로 다가가자 대황을 따는 남자가 보였습니다. 이런! 나는 초콜릿 실크파이를 더 좋아한다.