fork의 모든것

이동윤·2024년 11월 15일
0

fork()

이번 글에서는 함수에 대해 배워보겠습니다잉

fork()는 이미 실행 중인 프로세스를 복사해서 새로운 프로세스를 생성하는 함수입니다

  • 복제된 프로세스는 부모 프로세스의 동일한 메모리 영역복사하여 생성됩니다.
  • 새로 생성된 프로세스를 자식 프로세스라고 합니다.
  • 부모와 자식은 독립적으로 실행되며, 서로 영향을 주지 않는 별도의 프로세스로 동작합니다.

1. 함수 형식

#include <unistd.h>

pid_t fork(void);
  • 헤더 파일: <unistd.h>
  • 반환 타입: pid_t (프로세스 ID를 나타내는 정수형)

2. 매개변수 (인자)

  • fork() 함수는 인자를 받지 않습니다.
  • 함수 호출 시, 호출한 프로세스를 복사하여 새로운 자식 프로세스를 생성합니다.

3. 리턴값

양수 : 부모 프로세스에서 반환되며, 생성된 자식 프로세스의 PID를 반환.

0 : 자식 프로세스에서 반환되며, 자식 프로세스가 실행 중임을 나타냄.

-1 : fork() 호출 실패시 반환

  • fork() 의 반환값을 통해 부모와 자식을 구분할 수 있습니다는 것!

그렇다면 본격적으로 fork에 대해서 알아봅시다!!


fork() 호출 이후 kernel 동작 과정

  • (a) 새로운 메모리와 데이터 구조 할당
  • (b) 원래 process의 code와 data를 새로운 process에 복사(코드와 데이터 동일)
  • (c) 새로운 process를 실행 중인 프로세스의 리스트에 추가
  • (d) 두 process에게 제어권을 넘김

#include <stdio.h>
#include <unistd.h>
int main()
{
	printf("my pid is %d\n", getpid());		//원본 pid 출력
	fork();	// 프로세스 개수 : 2
	fork();	// 프로세스 개수 : 4
	fork(); // 프로세스 개수 : 8
	printf("my pid is %d\n", getpid());
	return 0;
}

부모와 자식의 데이터는 별개이다!

들어가기에 앞서, 왜 fork라는 함수 이름을 가졌을까?

fork()의 호출 및 생성 과정을 시각적으로 보면 프로세스가 두 갈래로 나뉘는 것처럼 보이는데, 말그대로 포크와 유사합니다.

유닉스 철학에서의 비유하자면 유닉스 시스템에서, fork()는 새로운 작업을 병렬적으로 처리하는 데 필수적인 도구입니다.

시스템의 흐름에서 실행 중인 프로세스를 복제하여 독립적인 두 작업이 서로 다른 경로를 갈라져 수행된다는 점이 중요하다는 것!


우리는 이 독립적이라는 키워드에 집중해봅시다
부모 프로세스와 자식 프로세스의 지역변수는 느낌적인 느낌만으로도 각각 다른 값을 가진다는 것을 알 수 있습니다

그러나 전역변수는 뭔가 공유를 할것만 같은 느낌이 듭니다. (나만 그런거라면 깝까비)

그러나, 전역변수조차도 두 프로세스에서 각각 다른값을 가집니다.

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int gval=10;	// 전역 변수

int main(int argc, char *argv[])
{
	pid_t pid;
	int lval=25;	// 지역 변수
	pid=fork();

	if(pid==0) // Child Process
	{
		gval+=2, lval+=2;
		printf("Child Proc: [%d, %d] \n", gval, lval);
	}
	
    else // Parent Process
	{
	gval-=2, lval-=2;
	printf("Parent Proc: [%d, %d] \n", gval, lval);
	}
    
	return 0;
}

출력결과

$ gcc fork_ex.c -o fork_ex
$ ./fork_ex
Parent Proc: [8, 23]
Child Proc: [12, 27]

0개의 댓글