2012-01-13 3 views
7

포크 시스템 호출 코드는 어떻게 작성됩니까? 함수가 두 개의 다른 값을 반환 할 수있는 방법과 두 개의 다른 프로세스를 반환하는 방법에 대해 자세히 알고 싶습니다. 간단히 포크 시스템 호출이 어떻게 구현되는지 알고 싶습니까?포크 구현

+3

리눅스 커널 소스 코드를 살펴볼 수 있습니다 ... – fge

+1

OS가 프로세스를 생성 할 수 있다는 생각에 편안하고 각 프로세스의 주소 공간에 매핑 할 메모리 영역을 선택할 수 있습니까? –

+0

이 질문에 어떤 점이 있습니까? – Svisstack

답변

9

당신은 시스템 호출이라고 말하면서 설명했습니다. 운영 체제는 모든 작업을 수행하는 작업이며 운영 체제는 프로그램의 컨텍스트 외부에서 원하는 모든 작업을 수행하거나 구현할 언어의 규칙을 거의 수행 할 수 있습니다. 여기에 간단한 예제가 있습니다. 일 :

  1. 프로그램 (fork() 시스템 호출
  2. 커널 포크 시스템 콜이 프로그램 커널은 원래 프로그램과 중복에 대한 시스템 호출의 반환 값을 설정
  3. 를 실행하는 과정을 복제의 PID 호출 duplicate와 0, 각각)
  4. 커널은 두 프로세스를 스케줄러 큐
  5. 각 프로세스가 스케줄 될 때 커널은 두 프로그램 각각에 '리턴'합니다.

    return pid; 
    return 0; 
    

    먼저 처리가 먼저 실행된다 : 예시적인 프로세스 쉬운 방법

-1

과 같을 수있는 기능의 일부 지시를 건너 IP/EIP/RIP에게 레지스터 움직이는 fork() 함수 클로닝 명령 및 팝 함수가 스택에서 시작되지만 두 번째 프로세스는 0을 반환하는 두 번째 명령에서 시작합니다.

+0

나는 각 프로세스의 시스템 호출에서 다른 값을 반환하는 커널이라고 생각합니다. – tangrs

+0

fork()를 호출 할 때 두 지점 모두 프로세스 포크입니다. "두 번째"프로세스 (부모 또는 자식)가 무엇을 의미하는지 알지 못하지만 – iantonuk

2

Unix V6 Ken Thomps가 주석을 첨부 한 대학의 소스 코드 책자에는 설명이 있습니다 데니스 리치 (Dennis Ritchie)와 더블 리턴 (Double Return)이 실제로 어떻게 작동하는지 설명하고 있습니다. 그 주석은 다음 문장으로 끝납니다 :

당신은 이것을 이해하지 못할 것입니다.

+0

IIRC는 두 번 자체를 반환 할 생각이 아니라 사용 된 어셈블리를 참조했습니다. – ninjalj

7

칼의 대답은 훌륭했습니다. 많은 운영 체제에서 반환 값이 레지스터 중 하나에 전달된다는 것을 추가하고 싶습니다. x86 아키텍처에서이 레지스터는 eax 일 수 있습니다. ARM 아키텍처에서이 레지스터는 R0 일 수 있습니다.

각 프로세스에는 프로세스 제어 블록 (PCB)이 있습니다. 프로세스 제어 블록 (PCB)은 인터럽트, 시스템 호출 또는 예외가 발생하고 컨트롤이 OS로 전달되었습니다. 다음에 프로세스가 스케줄되면 레지스터 값이 PCB에서 복원됩니다. 포크()가 발생했을 때

이제, OS 할 수있다 : 프로세스가 재조정 될 때

child_process->PCB[return_value_register] = 0; 
parrent_process->PCB[return_value_register] = child_pid; 

그래서, 그들 각각은 서로 다른 반환 값을 참조하십시오.

예를 들어, xv6's implementation of fork을 볼 수 있습니다. 거기서, 부모 프로세스는 여전히 실행 상태이므로, 간단한 return 문을 사용하여 부모의 리턴 값을 반환합니다. 그러나 0으로 자식 프로세스에 대한 EAX 레지스터의 값을 설정, 그래서 자식 프로세스가 예약 된 경우는 반환 값으로 0을보고 : 0은 또한 "mov 인 EAX, 0"같은 것으로 컴파일 돌아

// Clear %eax so that fork returns 0 in the child. 
np->tf->eax = 0; 

참고.

업데이트 : 방금 ​​내가 취미로 사용하는 OS에 fork()를 구현했습니다. 소스 코드 here을 볼 수 있습니다.