프로세스와 쓰레드
2020, Feb 01
Program: 실행 가능한 코드, 바이너리로 파일로 저장되어 있습니다.Process: 실행 중인 프로그램입니다. 프로세스는 프로그램의 이미지, 메모리 인스턴스, 커널 리소스 등의 정보를 포함합니다. 그리고 하나의 프로세스에는 하나 이상의 쓰레드를 포함하고 있습니다.Thread: 프로세스의 실행 단위입니다. 가상화된 프로세스, 스택, 레지스터 및 명령어 포인터 등 프로세서의 상태를 포함하고 있습니다. 프로세스 내의 모든 쓰레드는 같은 주소 공간을 공유합니다. 특히, 글로번 변수 같은 경우는 쓰레드들 끼리 공유됩니다.(로컬 변수는 공유 안됨)

- 프로세스가 가지는 메모리 영역을 표현하면 위와 같이 표시할 수 있습니다.
- 여기서
max가 메모리의 최대값을 나타냅니다. - 프로세스가 메모리에 올라가게 되면 위 그림과 같이 크게 4가지 영역으로 나뉘게 됩니다.
text 영역은 compile된 프로그램의 코드가 올라가게 됩니다. (object 파일, executable 파일 등)data 영역은 다양한 데이터가 있는데 기본적으로 전역 변수가 들어간다고 보면 됩니다.head 영역은 동적 메모리를 할당할 때 사용되는 영역입니다.stack 영역은 동적 메모리 할당에 사용되지 않고 함수의 로컬 변수나 함수를 호출하거나 리턴할 때 사용됩니다.(재귀 함수 시에도 사용됨)
- 위 그림처럼
stack과heap의 메모리가 누적되는 방향이 다릅니다. 따라서stack의 크기가 커지거나heap의 크기가 커져서 꽉 차게 되면 메모리 영역에 stack과 heap 메모리가 마주치게 됩니다. - 물론 메모리 해제가 발생하면 다시 쌓였던 메모리가 없어지게 됩니다.

- 위 그림은 하나의 프로세스에서 쓰레드가 하나인 경우와 쓰레드가 여러개인 경우의 상태를 나타냅니다.
- 쓰레드가 여러개이더라도 code, data, file들은 공유가되고 register, stack들은 각 쓰레드별로 따로 가지는 것을 알 수 있습니다.

- 프로세스들은 위 그림과 같이 계층 구조를 가지고 있습니다.
- 이 계층 구조에서 상위 구조에 있는 프로세스가 부모(Parent) 프로세스이고 하위 구조에 있는 프로세스가 자식(Child) 프로세스입니다. 즉 트리 형태를 가지게 됩니다.
- 이렇게 계층구조를 가지는 이유는 부모 프로세스가 자식 프로세스를 생성할 수 있기 때문입니다.
- 각 노드를 보면 프로세스의 이름 이외에 프로세스의 아이디인
pid가 있습니다.pid는 프로세스 별로 유니크한 값을 가지게 되어 프로세스를 식별할 수 있는 아이디가 됩니다. - 가장 상위 계층인
init프로세스는 커널이 부팅하는 과정에서 만들어 주는 프로세스로 가장 상위 계층에 있는 프로세스이고 부모 프로세스는 없습니다. 가장 처음 만들어지는 프로세스이므로pid = 1입니다. - 그러면 어떻게 프로세스를 복제 및 생성하는 지 알아보도록 하겠습니다.

- 첫번째로 알아볼 API는
fork입니다. - 부모 프로세스에서
fork를 실행하면 자식 프로세스를 하나 만들어 주는데 이 떄, 부모 프로세스의 메모리 상태를 그대로 복사해서 자식 프로세스를 만들게 됩니다. - 복제된 2개의 프로세스가 생기므로 구분을 할 필요가 있는데,
fork를 성공적으로 호출하였을 때, 반환값으로pid_t라는 정수 형태의 값을 반환받는데 이 값을 통하여 부모 프로세스와 자식 프로세스를 구분하고 있습니다. - 성공적으로 호출하였을 때, 부모 프로세스의 경우 자식 프로세스의
pid를 반환받게 되고 자식 프로세스의 경우에는 0 값을 반환받으므로 부모와 자식 프로세스가 어떤 것인 지 구분할 수 있습니다. (이후에 살펴볼 코드를 보시면 더 자세하게 이해하실 수 있습니다.) - 호출을 실패하였을 때, 부모 프로세스는 -1의 값을 가지게 되고 자식 프로세스는 생성되지 않습니다.
- 즉,
부모 프로세스 기준으로 반환값이 양의 값을 가지면 fork가 성공적으로 호출되어 자식 프로세스가 생성된 것이고 음수 값을 가지면 fork 호출이 실패한 것입니다.

- 현재 프로세스 관련
pid를 알아보기 위해서는getpid와getppidAPI를 사용할 수 있습니다. - 현재 프로세스의
pid를 알아보려면getpid를 사용하여 확인할 수 있고 현재 프로세스의 부모 프로세스를 알아보려면getppid함수를 이용하면 됩니다.