우리가 알고있던 프로그램이 실행되면 CPU에서 프로세스라는 것으로 실행된다는 것을 알았다. 그렇다면 프로세스는 어떻게 생성되고 복사되는지 알아보자.
1. 프로세스의 구조
: 프로세스는 코드영역, 데이터 영역, 스택영역으로 구성된다. 예를 들어 워드프로세서 프로그램을 실행하면 이 프로그램은 코드 영역에 탑재되고, 워드프로세서로 편집중인 문서는 데이터 영역에 탑재된다. 또한 운영체제가 워드프로세서를 작동하기 위해 사용하는 각종 부가 데이터는 스택 영역에서 관리한다. 이렇듯 프로그램이 프로세스가 될려면 3가지 영역이 유기적으로 작동한다.
- 코드 영역 code area : 프로그램의 본문이 기술된 곳으로 텍스트 영역text area 라고도 한다. 프로그래머가 작성한 프로그램은 코드영역에 탑재되며 탑재된 코드는 읽기 전용으로 처리된다. 자기 자신을 수정하는 프로그램은 존재하지 않기 때문이다.
- 데이터 영역 data area : 코드가 실행되면서 사용하는 변수variable나 파일 등의 각종 데이터를 모아놓은 곳이다. 데이터는 변하는 값이기 때문에 이곳의 내용은 기본적으로 읽기와 쓰기가 가능하다.
- 스택 영역 stack area : 운영체제가 프로세스를 실행하기 위해 부수적으로 필요한 데이터를 모아놓은 곳이다. 예를 들어 프로세스 내에서 함수를 호출하면(function call)함수를 수행하고 원래 프로그램으로 되돌아 올 위치를 이 영역에 저장한다. 스택 영역은 운영체제가 사용자의 프로세스를 작동하기 위해 유지하는 영역이므로 사용자에게는 보이지 않는다.
2. 프로세스의 생성과 복사
: 프로세스는 프로그램을 실행할 때 새로 생성된다. 사용자가 프로그램을 실행하면 운영체제는 프로그램을 메모리로 가져와 코드 영역에 넣고 프로세스 제어 블록을 생성한다. 그리고 메모리에 데이터 영역과 스택 영역을 확보한 후 프로세스를 실행한다.
그런데 프로세스를 새로 생성하는 방법뿐만 아니라 실행중인 프로세스로부터 새로운 프로세스를 복사하는 방법도 있다.
2.1 fork()시스템 호출의 개념
fork() 시스템 호출은 실행중인 프로세스로부터 새로운 프로세스를 복사하는 함수이다. 커널에서 제공하는 이 함수는 프로세스를 복사하는 일종의 시스템 호출이다. fork() 시스템 호출을 사용하면 실행중인 프로세스와 똑같은 프로세스가 하나 더 만들어진다. 이렇게 복사해서 실행하면 처음 실행하는 속도보다 훨씬 빠르다.
또 다른 예로 구글의 웹브라우저인 크롬에서 어떤 웹사이트를 보다가 ctrl+N을 누르면 크롬 웹페이지가 하나 더 실행된다.
**fork() 시스템 호출**
: fork() 시스템 호출은 실행 중인 프로세스를 복사하는 함수이다. 이때 실행하던 프로세스는 부모 프로세스, 새로 생긴 프로세스는 자식 프로세스로서 부모-자식 관계가 된다.
2.2 fork() 시스템 호출의 동작 과정
fork() 시스템 호출을 하면 시스템 내부에서는 어떤 일이 일어날까?
fork() 시스템 호출을 하면 프로세스 제어 블록을 포함한 부모 프로세스 영역의 대부분이 자식 프로세스에 복사되어 똑같은 프로세스가 만들어진다. 단, 프로세스 제어 블록의 내용 중 일부가 변경되는데 변경되는 부분은 다음과 같다.
- 프로세스 구분자(PID)가 바뀐다. 이는 부모와 자식의 주민등록번호가 다른 것과 마찬가지이다.
- 부모 프로세스와 자식 프로세스가 차지하고 있는 메모리의 위치가 다르므로, 메모리 관련 정보가 바뀌게 된다.
- 부모 프로세스 구분자PPID와 자식 프로세스 구분자CPID가 바뀐다(둘은 부모-자식 관계이기 때문)
2.3 fork() 시스템 호출의 장점
- 프로세스의 생성 속도가 빠르다
- 추가 작업 없이 자원을 상속할 수 있다
- 시스템 관리를 효율적으로 할 수 있다
2.4 fork() 시스템 호출의 사용
: fork() 함수는 unistd.h 헤더를 포함한 후 사용가능하다. fork() 문은 부모프로세스에 0보다 큰 값, 자식 프로세스에 0을 반환한다. fork()문 이전에 파일을 열거나 변수를 선언하면 이것이 모두 자식 프로세스에 상속된다.
3. 프로세스의 전환
3.1 exec() 시스템 호출의 개념
: exec() 시스템 호출은 기존의 프로세스를 새로운 프로세스로 전환하는 함수이다.
- fork() : 새로운 프로세스를 복사하는 시스템 호출이다.
- exec() : 프로세스는 그대로 둔 채 내용만 바꾸는 시스템 호출이다. exec() 시스템 호출을 하면 현재의 프로세스가 완전히 다른 프로세스로 전환된다.
exec() 시스템 호출을 사용하는 목적은 프로세스의 구조체를 재활용하기 위함이다. 새로운 프로세스를 만들려면 프로세스 제어 블록을 만들고 메모리의 자리를 확보하는 과정이 필요하다. 또한 프로세스를 종료한 후 사용한 메모리를 청소(garbage collection)하기 위해 상위 프로세스와 부모-자식 관계를 만들어야 한다. 이때 exec() 시스템 호출을 사용하면 이미 만들어진 프로세스 제어 블록, 메모리 영역, 부모-자식 관계를 그대로 사용할 수 있어 편리하다. 새로운 코드 영역만 가져오면 되기 때문에 운영체제의 작업이 수월하다.
3.2 exec() 시스템 호출의 동작 과정
exec() 시스템 호출 동작 과정은 간단하다. exec() 시스템 호출을 하면 코드 영역에 있는 기존의 내용을 지우고 새로운 코드로 바꿔버린다. 또한, 데이터 영역이 새로운 변수로 채워지고 스택 영역이 리셋된다. 프로세스 제어 블록의 내용 중 프로세스 구분자, 부모 프로세스 구분자, 자식 프로세스 구분자, 메모리 관련 사항 등은 변하지 않지만 프로그램 카운터, 레지스터 값을 비롯 각종 레지스터와 사용한 파일 정보가 모두 리셋된다. 마치 프로세스를 처음 시작하는 것처럼 내용이 정리된다.
'CS > 운영체제' 카테고리의 다른 글
[2] 시분할 시스템, 실시간 시스템 (0) | 2022.03.09 |
---|---|
[1] 운영체제의 발전 (0) | 2022.03.07 |
프로세스 제어블록(Process Control Block) (0) | 2020.10.29 |
프로세스의 개요 (0) | 2020.10.29 |
병렬처리 (0) | 2020.10.26 |