Process Control Block(PCB)
PCB는 프로세스의 모든 정보를 가지고 있다. OS가 프로세스 스케줄링을 위해 PCB의 정보를 사용한다.
즉 OS가 다른 프로세스로 전환할 때(Context switch), 처리되고있던 프로세스는 자신의 PCB에 작업 정보를 저장한다. 그러면 이 프로세스가 다음에 다시 CPU를 점유했을 때, 이전에 하던 작업을 이어서 처리할 수 있겠다.
∨ PCB의 생성과 제거
생성
참고: https://studyblog4244.tistory.com/109
↓ fork() 시스템 콜로 인해 생성된다. 자식 프로세스가 생성되는 것이다.
(유의: pid가 0인 Idle process는 그렇지 않음. os가 수동으로 생성함)
↓ 새로운 프로세스 생성시 PCB가 생성되며, 하나의 프로세스당 하나의 PCB가 생성된다.
↓ 자식 프로세스에게 PID(process identifier)를 배정한다. 나머지는 (대부분) 부모 프로세스와 동일한 값으로 세팅한다. 더욱 상세한 설명은 fork()를 이해하면 된다.
↓ 모든 프로세스들은 부모-자식 및 형제간 연결이 되어있어서, 프로세스간 연결 맺는 과정도 필요하다. 리눅스에서는 프로세스 리스트라는 자료구조를 이용해 PCB를 연결지어 관리한다.
↓ 자식 프로세스의 User Context를 생성한다. 가장 오래 걸리는 과정이다. 이때 자식프로세스는 일반적으로 COW(Copy On Write) 방식을 통해 User Context를 관리해간다. → COW에 대한 부가설명: 자식 프로세스가 갓 생성이 되었을 때, context는 부모의 것과 다름 없을 것이다. 그런데 자식의 context 생성 시점에, 부모 것을 그대로 copy하여 '별도로 갖고 있는 것이 아니다'. 생성 직후에는 부모의 context를 그대로 참조하고 있다가, 자식 프로세스에서 데이터가 변경되는 시점에 copy한다. 그제서야 자식프로세스는 메모리상에 별도의 context를 가지게 된다. 즉 copy가 생성시점에 되는 게 아니라, copy on write! ← 참고로, 이 copy on write는 exec() 시스템콜에 적극 적용된다. (더 궁금하다면 https://studyblog4244.tistory.com/109를 참고하자)
↓ 여기까지 new 상태에 대한 과정이 모두 완료되었다. 이제 생성된 자식 프로세스를 ready queue에 삽입하여 OS가 실행해주도록 기다리게 된다.
↓ 마지막으로 fork()를 호출한 부모프로세스에게 자식의 pid를 리턴하며, fork()를 마친다.
* 참고: fork()를 통해 복제된 자식프로세스는 exec()을 통해 자신 프로세스의 메모리 공간을 새로운 (실행할) 프로그램으로 덮어쓴다. code, data영역은 실행할 프로그램 내용으로 덮어써지고, 나머지 영역은 초기화된다. 만약 fork()를 통해 복제된 자식프로세스, 또는 부모프로세스 스스로가, exec()를 호출하지 않는 케이스에서는 두 프로세스(부모, 자식)은 동일 코드를 병행해서 실행하는 상태다.
제거
- 프로세스가 종료된 이후 wait() 시스템콜을 호출하면 PCB는 제거된다.
* 참고: 프로세스 종료 후 wait()를 쓰면 이제 진짜로 PCB까지 회수한다.
PCB를 남기는 이유는, PCB에 있는 account 그니까 통계 정보를 위해서 남겨두고,
이것을 OS가 모두 읽었다면 wait() 시스템 콜을 통해서 프로세스는 완전히 끝나게 된다.
∨ PCB 구조
OS마다 세부 구조는 다를 수 있겠지만, 일반적으로 프로세스 속성 정보는 이러하다.
■ 식별자 (프로세스 그룹 식별자, 부모 프로세스의 식별자 PPID, 사용자의 식별자 PID... 0부터시작하는 정수값임)
■ 상태 (프로세스 상태 ... new, ready, running, blocked, terminated)
■ 우선순위
■ Program counter (다음에 실행할 명령어의 주소, PC)
■ Memory pointers
■ Memory context(프로그램 코드, 변수 등)
■ I/O 상태 정보(이 프로세스에 할당된 I/O장치들 정보, 열려있는 파일 정보)
■ 통계 정보 (Accounting information - CPU 사용시간 등)
.
.
이해를 돕기 위해 다음 PCB 구조를 도면으로 확인해보자.
두 사진은 다른 곳에서 가져온 건데, 두개를 슥 보면 program counter, state, priority, address 관련 정보, 열린 파일 정보들.. 등등.. 그러한 것들을 담고 있다.
이렇게.. 프로세스를 나타내는 구조체가 PCB인 것이다.
PCB의 Program Counter로 이해해보는 Context Switching!
PCB가 Program counter 값을 저장한다고 했다.
간단히 생각해보면 "다음번에 실행할 명령어의 주소를 저장하는구나" 할 수 있다.
Context Switching이 일어날 때, PC를 꺼내와서 해당 프로세스의 명령을 이어서 작업할 수 있고 말이다.
이 과정을 좀 더 풀어서 짚어보자. 좀 더 구체적인 설명을 섞어보자는 것..
Program counter(PC)는 CPU 내부의 레지스터다. CPU는 다음에 실행할 명령어를 이 PC 레지스터에 저장한다는 것을 기억하자. CPU는 현재 잡고있는 프로세스의 명령어들을 활발히 수행할텐데, 다음에 실행할 명령어의 주소를 PC레지스터에 저장하며 명령의 수행을 이어간다는 것을 되짚어보자.
그럼 이제,
Context Switching이 일어날 때 CPU의 PC값이 프로세스의 PCB에 저장되는 과정을 간단히 짚어보자.
A라는 프로세스가 CPU를 점유하며 수행되고 있다가 interrupt가 걸렸다고 하자.
그럼 A는 wait 상태가 될 것이다. OS는 Context Switching을 수행해야 한다.
A가 돌아갈 시점에 CPU의 레지스터 값들은 A 기준으로 세팅되어있을 것이다.
그러나 이제 B프로세스가 돌아가야 하므로 CPU의 레지스터 값은 새로운 B프로세스 기준으로 바뀌게 되는데, 그렇다면 너무나도 활발히 돌아가던 A프로세스의 작업정보(PC 등 레지스터 값)들은 어디에 저장해야 하는가?
바로바로 A프로세스 자신의 PCB에 저장한다! 그러면 다음에 A가 다시 CPU를 점유했을 때, OS는 A의 PCB에서 이전 프로세스 작업 상태를 읽어와서 CPU 레지스터에 값들을 적재한다. 그렇게 작업을 이어서 진행할 수 있다. (이게 곧 Context Switching이다)
'컴퓨터구조 & OS' 카테고리의 다른 글
[가상메모리:SWAP] 건드리면 터지는 2GB 서버에 서비스올리기 (0) | 2024.04.27 |
---|---|
[OS] 터미널을 종료하면 프로세스도 종료된다 -- background로 실행하여 SIGHUP 시그널 피하기 (0) | 2024.02.26 |
[운영체제] 프로세스 상태도 (2) | 2023.09.28 |
[운영체제] 프로세스 스케줄링: 멀티프로그래밍 vs 타임쉐어링 (0) | 2023.09.27 |
[python] gpu(cuda) 프로세스 정리하기 (0) | 2023.09.12 |