fork 함수
3170 단어 프로그래밍 감각
c 프로그램 구성 요소는 다음과 같습니다.
Text segment, 본문 세그먼트, CPU가 실행하고 명령하는 부분은 공유할 수 있으며, 보통 읽기만 합니다.
Initialized data segment, 데이터 세그먼트를 초기화하고 프로그램의 초기 값을 명확하게 지정해야 하는 변수를 포함합니다.
initialized data segment, 비초기화 데이터 세그먼트, 비초기화 데이터 세그먼트, 일명 bss 세그먼트(block started by symbol, 기호로 시작하는 세그먼트), 프로그램이 실행되기 전에 커널에서 0 또는 빈 포인터로 초기화됩니다.
Stack, 창고, 자동 변수와 매번 함수 호출에 필요한 정보를 저장하고, 프로그램이 귀속될 때 창고에 귀환 주소와 호출자의 환경 정보를 저장합니다.
Heap, 더미, 보통 더미에서 동적 저장 분배를 하는데 비초기화 데이터 세그먼트와 창고 사이에 있습니다.
일반적인 스토리지 스케줄은 그림과 같습니다.
[img]http://dl.iteye.com/upload/attachment/472396/d24d839c-9ec7-3800-827a-7fa8972fc440.png[/img]
프로세스에는 주로 세 가지 요소가 포함됩니다.
실행 가능한 프로그램
이 프로세스와 관련된 모든 데이터 (변수, 메모리 공간, 버퍼 등 포함)
프로그램 실행 컨텍스트
운영체제의 프로세스에 대한 관리는 전형적인 상황으로 프로세스 테이블을 통해 이루어진다.프로세스 테이블의 모든 테이블 항목은 현재 운영체제의 프로세스 상황을 기록합니다.어떤 프로세스에 나누어 주는 CPU 시간이 다 되면 운영체제는 이 프로세스와 관련된 레지스터의 값을 프로세스 테이블에 대응하는 항목에 저장한다.이 프로세스가 CPU를 차지하는 프로세스를 대체할 상하문을 프로세스 테이블에서 읽고 해당하는 레지스터를 업데이트합니다. 이 과정을 상하문 교환 (process context switch) 이라고 합니다.
그 다음에 fork () 는 fork에서 만든 새 프로세스를 하위 프로세스 (childprocess) 라고 하는데, 운영체제는 프로세스 테이블에서 하위 프로세스에 해당하는 새 테이블 항목을 만듭니다.fork 함수는 "한 번 호출하고 두 번 되돌려준다"는 특성이 있습니다.이것은 호출 프로세스(parent process)에서 한 번 되돌아오며 되돌아오는 값은 하위 프로세스의 ID 번호입니다.하위 프로세스에서 다시 한 번 되돌아왔습니다. 되돌아오는 값은 0입니다.따라서 현재 프로세스가 부모 프로세스인지 하위 프로세스인지 되돌아오는 값을 통해 판단할 수 있습니다.
부모 프로세스가 fork를 호출하기 전에 열린 모든 설명을 fork가 되돌아온 후에 하위 프로세스에서 공유합니다. 즉, 하위 프로세스는 부모 프로세스의 복사본이며, 부모 프로세스의 데이터 공간, 더미, 창고의 복사본을 가져옵니다.이것은 공유가 아니라 복사입니다. 아버지 프로세스와 하위 프로세스가 공유하는 것은 본문입니다.(전면 그림 참조)
fork()의 두 가지 일반적인 사용 방법은 다음과 같습니다.
하나의 프로세스가 자신의 복사본을 생성합니다. 이렇게 하면 모든 복사본은 다른 작업을 수행하는 동시에 각자의 작업을 처리할 수 있습니다. 이것은 네트워크 프로그래밍에서 흔히 볼 수 있는 것입니다.
하나의 프로세스가 다른 프로그램을 실행하려고 합니다.새 프로세스를 만드는 유일한 방법은 fork를 호출하는 것입니다. 따라서 우리는 fork로 복사본을 만들고 하위 프로세스에서 exec를 호출해서 자신을 새 프로그램으로 바꿀 수 있습니다.
다음은 간단한 fork() 예입니다.
#include
#include
int main(void)
{
fork();
printf("P1
");
fork();
printf("P2
");
}
fork 이후에 부모 프로세스가 먼저 실행되는지 하위 프로세스가 먼저 실행되는지는 확실하지 않습니다. 이것은 내부에서 사용하는 스케줄링 알고리즘에 달려 있습니다.
#include
#include
int main(void)
{
pid_t pid;
printf("fork!
");
pid=fork();
if (pid < 0)
printf("error in fork!");
else if (pid == 0)
printf("i am the child process, my process id is %d
",getpid());
else
printf("i am the parent process, my process id is %d
",getpid());
}
출력 결과는 다음과 같습니다.
fork!
i am the child process, my process id is 4286
i am the parent process, my process id is 4285
왜 여기 포크!한 번만 출력할까요?비교를 위해 printf("fork!")를 사용할 수 있습니다.안에 있는 거 빼고, 이럴 때 프로그램은 두 번 포크를 출력해!라..설명은 다음과 같다. 사실 이것은 printf의 버퍼 메커니즘과 관련이 있다. printf의 일부 내용을 볼 때 운영체제는 이 내용을 stdout의 버퍼 대기열에 넣었을 뿐 실제 화면에 나타나지 않았다.그래서 포크 () 후 하위 프로세스가 이 복사를 받을 수 있습니다.printf () 에 때때로 printf가 stdout을 리셋하기 때문에 하위 프로세스가 이 복사를 받을 수 없습니다. fork!당연하게 한 번만 출력하는 거지.