포크 시스템 콜 리눅스

Fork System Call Linux



fork 시스템 호출은 새 프로세스를 만드는 데 사용됩니다. 새로 생성된 프로세스는 자식 프로세스입니다. fork를 호출하고 새로운 프로세스를 생성하는 프로세스가 부모 프로세스입니다. 자식 프로세스와 부모 프로세스가 동시에 실행됩니다.

그러나 자식 프로세스와 부모 프로세스는 서로 다른 메모리 공간에 있습니다. 이러한 메모리 공간은 동일한 내용을 가지며 한 프로세스에서 수행되는 모든 작업은 다른 프로세스에 영향을 주지 않습니다.







자식 프로세스가 생성될 때 이제 두 프로세스 모두 동일한 프로그램 카운터(PC)를 가지므로 두 프로세스 모두 동일한 다음 명령어를 가리킵니다. 상위 프로세스에서 연 파일은 하위 프로세스에서도 동일합니다.



자식 프로세스는 부모와 정확히 동일하지만 프로세스 ID에 차이가 있습니다.



  1. 자식 프로세스의 프로세스 ID는 다른 모든 기존 프로세스의 ID와 다른 고유한 프로세스 ID입니다.
  2. 부모 프로세스 ID는 자식 부모의 프로세스 ID와 동일합니다.

자식 프로세스의 속성

다음은 자식 프로세스가 보유하는 속성 중 일부입니다.





  1. CPU 카운터 및 리소스 사용률은 0으로 재설정되도록 초기화됩니다.
  2. 상위 프로세스가 종료되면 prctl()의 PR_SET_PDEATHSIG 속성이 재설정되기 때문에 하위 프로세스는 신호를 수신하지 않습니다.
  3. fork()를 호출하는 데 사용되는 스레드는 자식 프로세스를 만듭니다. 따라서 자식 프로세스의 주소는 부모의 주소와 동일합니다.
  4. 상위 프로세스의 파일 디스크립터는 하위 프로세스에 상속됩니다. 예를 들어 파일의 오프셋 또는 플래그의 상태 및 I/O 속성은 자식 및 부모 프로세스의 파일 설명자 간에 공유됩니다. 따라서 부모 클래스의 파일 설명자는 자식 클래스의 동일한 파일 설명자를 참조합니다.
  5. 상위 프로세스의 열린 메시지 큐 설명자는 하위 프로세스에 상속됩니다. 예를 들어 파일 디스크립터가 상위 프로세스에 메시지를 포함하는 경우 동일한 메시지가 하위 프로세스의 해당 파일 디스크립터에 표시됩니다. 따라서 이러한 파일 디스크립터의 플래그 값은 동일하다고 말할 수 있습니다.
  6. 마찬가지로 열린 디렉터리 스트림은 자식 프로세스에 의해 상속됩니다.
  7. 자식 클래스의 기본 Timer slack 값은 부모 클래스의 현재 타이머 slack 값과 동일합니다.

자식 프로세스가 상속하지 않는 속성

다음은 자식 프로세스에서 상속되지 않는 속성 중 일부입니다.

  1. 메모리 잠금
  2. 자식 클래스의 보류 신호가 비어 있습니다.
  3. 관련 레코드 잠금 처리(fcntl())
  4. 비동기식 I/O 작업 및 I/O 내용.
  5. 디렉토리 변경 알림.
  6. alarm(), setitimer()와 같은 타이머는 자식 클래스에 상속되지 않습니다.

C에서 fork()

fork()에는 인수가 없으며 fork()의 반환 유형은 정수입니다. fork()를 사용할 때 다음 헤더 파일을 포함해야 합니다.



#포함하다
#포함하다
#포함하다

fork()로 작업할 때 유형에 사용할 수 있습니다. pid_t 프로세스 ID의 경우 pid_t가 에 정의되어 있습니다.

헤더 파일은 fork()가 정의된 곳이므로 fork()를 사용하려면 프로그램에 포함해야 합니다.

반환 유형은 에 정의되어 있고 fork() 호출은 에 정의되어 있습니다. 따라서 fork() 시스템 호출을 사용하려면 프로그램에 둘 다 포함해야 합니다.

fork() 구문

Linux, Ubuntu에서 fork() 시스템 호출의 구문은 다음과 같습니다.

pid_t 포크(무효);

구문에서 반환 유형은 pid_t . 자식 프로세스가 성공적으로 생성되면 부모 프로세스에서 자식 프로세스의 PID가 반환되고 자식 프로세스 자체에는 0이 반환됩니다.

오류가 있으면 부모 프로세스에 -1이 반환되고 자식 프로세스는 생성되지 않습니다.

No arguments are passed to fork(). 

예 1: fork() 호출

fork() 시스템 호출을 사용하여 새 자식 프로세스를 만든 다음 예제를 고려하십시오.

암호:

#포함하다
#포함하다
#포함하다

정수기본()
{
포크();
인쇄 ('fork() 시스템 호출 사용N');
반품 0;
}

산출:

fork() 시스템 호출 사용
fork() 시스템 호출 사용

이 프로그램에서 우리는 fork()를 사용했고 이것은 새로운 자식 프로세스를 생성할 것입니다. 자식 프로세스가 생성되면 부모 프로세스와 자식 프로세스 모두 다음 명령어(동일한 프로그램 카운터)를 가리킵니다. 이런 식으로 나머지 명령어 또는 C 문은 총 프로세스 횟수, 즉 2번으로 실행됩니다.N여기서 n은 fork() 시스템 호출 횟수입니다.

따라서 fork() 호출이 위와 같이 한 번 사용되면(21= 2) 출력은 2번입니다.

여기서 fork() 시스템 호출이 사용되면 내부 구조는 다음과 같습니다.

fork()가 4번 사용되는 다음 경우를 고려하십시오.

암호:

#포함하다
#포함하다
#포함하다

정수기본()
{
포크();
포크();
포크();
포크();
인쇄 ('fork() 시스템 호출 사용');
반품 0;
}

산출:

Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call 

이제 생성된 총 프로세스 수는 2입니다.4= 16이고 print 문을 16번 실행했습니다.

예 2: fork()가 성공했는지 테스트

다음 예에서 우리는 fork()에 의해 반환된 값(int)을 테스트하기 위해 의사 결정 구조를 사용했습니다. 해당 메시지가 표시됩니다.

암호:

#포함하다
#포함하다
#포함하다

정수기본()
{
pid_t 피;
NS=포크();
만약(NS== -1)
{
인쇄 ('fork()를 호출하는 동안 오류가 발생했습니다');
}
만약(NS==0)
{
인쇄 ('우리는 자식 프로세스에 있습니다');
}
또 다른
{
인쇄 ('우리는 부모 프로세스에 있습니다');
}
반품 0;
}

산출:

우리는 부모 프로세스에 있습니다
우리는 자식 프로세스에 있습니다

위의 예에서 우리는 fork()의 반환 값을 저장할 pid_t 유형을 사용했습니다. fork()는 온라인에서 호출됩니다.

NS=포크();

따라서 fork()에서 반환된 정수 값은 p에 저장되고 p는 fork() 호출이 성공했는지 확인하기 위해 비교됩니다.

fork() 호출을 사용하여 자식이 성공적으로 생성되면 자식 프로세스의 id가 부모 프로세스로 반환되고 0이 자식 프로세스로 반환됩니다. 부모 프로세스의 자식 프로세스 ID는 동일하지 않습니다. 자식 프로세스 자체에 있는 자식 프로세스의 ID입니다. 자식 프로세스에서 자식 프로세스의 ID는 0입니다.

이 튜토리얼을 통해 Linux에서 fork 시스템 호출을 시작하는 방법을 볼 수 있습니다.