본문 바로가기
Lecture/OS

프로세스의 연산

by YUNZEE 2023. 10. 17.
728x90
프로세스의 구조

프로세스는 코드 영역, 데이터 영역, 스택 영역으로 구성되어 있다.

코드 영역 code area

코드 영역은 프로그램의 본문이 기술된 곳으로 텍스트 영역 이라고도 한다. 프로그래머가 작성한 프로그램은 코드 영역에 탑재되며 탑재된 코드는 읽기 전용으로 처리된다. 자기 자신을 수정하는 프로그램은 존재하지 않기 때문이다.

 

데이터 영역 data area

데이터 영역은 코드가 실행되면서 사용하는 변수나 파일 등의 각종 데이터를 모아놓은 곳이다. 본문에 사용되는 데이터가 저장되어 있다. 데이터는 변하는 값이기 때문에 이곳의 내용은 기본적으로 읽기와 쓰기가 가능하다. 

 

스택 영역 stack area

스택 영역은 운영체제가 프로세스를 실행하기 위해 부수적으로 필요한 데이터를 모아놓은 곳이다. 예를 들어 프로세스 내에서 함수를 호출하면 function call함수를 수행하고 원래 프로그램으로 되돌아올 위치를 이 영역에 저장한다. 

 

프로세스의 생성과 복사

프로세스는 프로그램을 실행할 때 새로 생성된다. 사용자가 프로그램을 실행하면 운영체제는 프로그램을 메모리로 가져와 코드 영역에 넣고 프로세스 제어 블록을 생성한다. 그리고 메모리에 데이터 영역과 스택 영역을 확보한 후 프로세스를 실행한다.

 

fork() 시스템 호출의 개념

fork() 시스템 호출은 실행 중인 프로세스로부터 새로운 프로세스를 복사하는 함수로 커널에서 제공한다. fork() 시스템 호출을 사용하면 실행 중인 프로세스와 똑같은 프로세스가 하나 더 만들어진다. 같은 요리를 복사하듯이 하나 더 만드는 것이다. 프로세스를 복사할 때 기존 프로세스는 부모 프로세스가 되고 새로 생긴 프로세스는 자식 프로세스가 되어, 두 프로세스는 부모-자식 관계로 연결된다.

 

fork() 시스템 호출의 동작 과정

fork() 시스템 호출을 하면 시스템 내부에서 어떤 일이 일어날까?

fork() 시스템 호출을 하면 프로세스 제어 블록을 포함한 부모 프로세스 영역의 대부분이 자식 프로세스에 복사되어 똑같은 프로세스가 만들어진다. 단, 프로세스 제어 블록의 내용 중 일부가 변경되는데 변경되는 부분은 다음과 같다.

- 프로세스 구분자(PID)가 바뀐다. 이는 부모와 자식의 주민등록번호가 다른 것과 같다. 

- 부모와 자식 프로세스가 차지하는 메모리의 위치가 다르므로 메모리 관련 정보가 바뀐다.

- 부모 프로세스 구분자와 자식 프로세스 구분자가 바뀐다. 자식 프로세스에서는 부모 프로세스를 가리키는 부모 프로세스 구분자가 바뀌고 자식프로세스가 없으므로 자식 프로세스 구분자의 값이 -1이다.

 

 fork() 시스템 호출의 장점

- 프로세스의 생성 속도가 빠르다.

- 추가 작업 없이 자원을 상속할 수 있다.

- 시스템 관리를 효율적으로 할 수 있다.

 

fork() 시스템 호출의 예

부모 프로세스가 Parent를 출력하고 자식 프로세스는 child를 출력하여 결론적으로  둘 다 출력된다. 기억해야 할 점은 fork() 문 이전에 파일을 열거나 변수를 선언하면 이것이 모두 자식 프로세스에 상속된다는 것이다. 그러나 부모 프로세스와 자식 프로세스가 서로 독립적이기 때문에 Parent와 Child 중 어떤 것이 먼저 출력될지는 알 수 없다.

 

프로세스의 전환

exec() 시스템 호출의 개념

exec() 시스템 호출은 기존 프로세스를 새로운 프로세스로 전환하는 함수다. 요리에 비유하여 exec()시스템 호출의 개념을 이해해 보자.

fork() 시스템 호출이 스파게티를 하나 더 만드는 것이라면, exec()시스템 호출은 스파게티를 우동으로 바꾸는 것이다. 기존 스파게티 fork()와 exec()를 같이 사용하면 새로운 우동 하나가 만들어진다.

fork()는 새로운 프로세스를 복사하는 시스템 호출이다. exec() 프로세스는 그대로 둔 채 내용만 바꾸는 시스템 호출이다. exec() 시스템 호출을 하면 현재의 프로세스가 완전히 다른 프로세스로 전환한다.

exec() 시스템 호출은 이미 만들어진 프로세스의 구조를 재활용하는 것이다.

 

exec() 시스템 호출의 예

부모 프로세스는 fork() 문을 실행하여 자식 프로세스를 생성하고 wait() 문을 실행하여 자식 프로세스가 끝날 때까지 기다린다. wait() 문을 사용해야 고아 프로세스가 안 생긴다. 좀 더 뒤에서 자세히 설명하도록 하겠다.

 

유닉스 프로세스 계층 구조

유닉스에서 커널이 처음 메모리에 올라와 부팅되면 커널 관련 프로세스를 여러 개 만드는데, 그중 init 프로세스는 전체 프로세스의 출발점이 된다. 운영체제는 프로세스를 효율적으로 관리하기 위해 init 프로세스를 만든 다음 나머지 프로세스를 init 프로세스의 자식으로 만든다. 운영체제에 있는 모든 프로세스는 init프로세스의 자식이 된다.

 

프로세스 계층 구조의 장점

- 여러 작업의 동시 처리

유닉스 운영체제는 여러 사용자를 동시에 처리하기 위해 fork() 시스템 호출로 login프로세스를 여러 개 만들어 사용자에게 나누어 준다. 또한 부모-자식 관계도 유지할 수 있다. 운영체제는 exec() 시스템 호출을 사용하여 login프로세스를 shell프로세스로 바꾼 뒤 사용자의 명령을 기다린다. 

-용이한 자원 회수

 

고아 프로세스와 좀비 프로세스

자식 프로세스가 종료되기 전에 부모 프로세스가 먼저 종료되면 자식 프로세스는 고아 프로세스(orphan process)가 된다. 고아 프로세스는 부모 프로세스가 먼저 종료되어 돌아갈 곳이 없는 프로세스를 가리킨다. 좀비 프로세스(zombie process)는 자식 프로세스가 종료되었는데도 부모 프로세스가 뒤처리하지 않을 때 발생한다.

exit() 또는 return() 문은 자식 프로세스가 작업이 끝났음을 부모 프로세스에 알리는 것이다.

728x90

'Lecture > OS' 카테고리의 다른 글

스케줄링의 개요  (0) 2023.10.18
스레드  (2) 2023.10.17
프로세스 제어 블록과 문맥 교환  (0) 2023.10.16
멀티 프로세싱  (4) 2023.10.16
컴퓨터 성능 향상 기술  (2) 2023.10.14