한빛출판사 정성호 저 <쉽게 배우는 운영체제>를 참고하여 작성하였습니다.

1. 프로세스의 개념

1) 프로세스의 정의

 저장장치에 저장되어 있던 프로그램이 실행을 위해 메모리에 올라오면 프로세스가 된다. 즉 프로그램은 정적인 상태이며 프로세스는 동적인 상태라고 할 수 있다.

 프로그램이 프로세스로 전환될 때, 운영체제는 프로그램을 메모리의 적당한 위치로 가져온 뒤에 작업 지시를 하는데 이 작업지시는 프로세스 제어 블록 (Process Control Block,PCB)을 통하여 이루어진다. 즉 프로그램이 프로세스가 되었다는 것은 운영체제로부터 프로세스 제어 블록을 받았다는 것을 의미한다. 이때 프로세스 제어 블록은 운영체제가 해당 프로세스를 위해 관리하는 데이터 구조이기 때문에 운영체제 영역에 만들어진다.

프로그램이 프로세스로 전환

2) 프로세스의 구조

 프로세스는 코드 영역, 데이터 영역, 스택 영억으로 구서오딘다. 코드 영역은 프로그램의 본문이 기술된 곳으로 읽기 전용으로 처리 된다. 데이터 영역은 코드가 실행되면서 사용하는 변수나 파일 등의 각종 데이터를 모아놓은 곳이다.  데이터는 변화하는 값이므로 읽기모드와 쓰기모드를 모두 지원한다. 마지막으로 스택영역은 운영체제가 프로세스를 실행하기 위해 필요한 데이터를 모아 놓은 곳으로, 사용자에게는 보이지 않는다.

프로세스의 구조

3) 프로세스 제어 블록 (PCB)

  프로세스 제어 블록은 프로세스를 실행하는데 필요한 정보를 보관하는 자료 구조로, 프로세스는 각각 고유의 프로세스 제어 블록을 가진다. 프로세스 생성 시 만들어져서 프로세스 실행이 끝나면 폐기된다.

프로세스 제어 블록의 구조

 위 그림은 프로세스 제어 블록의 구조이다. 포인터는 준비 상태나 대기 상태의 큐(Queue)를 구현할 때 사용된다. 준비상태에서는 CPU 스케줄링 기법에 따라 포인터를 이용하여 프로세스의 처리 순서를 정하며, 대기 상태에서는 같은 입출력을 요구한 프로세스끼리 연결할 때 사용된다. 그 외에도 프로세스 구분자, 프로세스 상태, 프로세스 카운터(다음 실행 될 명령어의 위치를 저장) 프로세스 우선순위, 레지스터와 메모리 및 할당 자원의 정보, 계정 정보 등을 포함한다. PPID와 CPID는 각각 parent process ID, Child process ID의 준말로 부모 프로세스와 자식 프로세스의 정보를 저장한다.

2. 프로세스의 상태

1) 프로세스 상태전이도

프로세스 상태전이도

 생성 상태는 프로세스가 메모리에 올라와 실행 준비를 완료한 상태이다. 프로세스는 프로세스 제어 블록(PCB)를 얻어 준비 상태로 진입한다. 준비 상태에서 프로세스는 CPU를 할당 받을 때까지 대기하며, CPU를 할당 받으면 실행 상태로 진입하여 작업을 수행한다. 이때 만약 제한된 시간 안에 작업을 완료하면 프로세스 제어 블록을 반환한 뒤 완료 상태로 진입하며, 그렇지 못할 경우 준비 상태로 되돌아가 다시 자신의 차례를 기다린다.

 만약 실행상태에서 프로세스가 입출력을 요청 받으면 대기 상태로 진입하여 사용자의 입출력을 기다리며, 입출력이 완료 되면 다시 준비상태로 진입한다.

 보류상태는 메모리에서 프로세스가 쫓겨나 하드디스크에서 대기하는 상태를 말한다. 메모리가 꽉 차서 일부 프로세스를 밖으로 내보내거나, 프로그램 오류가 발생했을 때, 입출력이 계속 지연될 때 등의 경우에 프로세스는 보류 대기 상태로 진입한다.

 

2) 문맥교환

 문맥교환은 CPU를 차지하던 프로세스가 나가고 새로운 프로세스를 받아들이는 작업을 의미한다. 즉 상태전이도에서 준비 상태와 실행 상태의 사이에서 일어나는 현상이다. 실행 상태에서 나가는 프로세스는 프로세스 제어 블록에 지금까지의 작업 내용을 저장하고, 준비 상태에서 실행 상태로 들어오는 프로세스의 경우에는 프로세스 제어 블록의 내용을 바탕으로 CPU를 다시 세팅한다.

3. 프로세스의 생성과 복사

1) fork()

  fork() 시스템 호출은 실행 중인 프로세스로부터 새로운 프로세스를 복사하는 함수로, 실행하던 프로세스는 부모 프로세스가 되고 새로 생긴 프로세스는 자식 프로세스가 된다. 부모 프로세스 영역의 대부분이 자식 프로세스에 복사되어지며, 프로세스 제어 블록의 프로세스 구분자와 메모리 관련 정보, PPID, CPID가 변경된다. fork() 시스템 호출을 사용하면 하드디스크에서 새로 프로그램을 가져오는 것이 아니고 기존 메모리에서 복사하므로 프로세스 생성 속도가 빠르다.

fork() 시스템 호출

2) exec()

  exex() 시스템 호출은 기존의 프로세스를 새로운 프로세스로 재사용 하는 함수이다. 즉 fork() 시스템 호출이 새로운 프로세스를 복사하는 것이라면 exec() 시스템 호출은 프로세스는 그대로 둔 채 내용만 바꾼다.  exec() 시스템 호출을 하면 코드 영역의 기존 내용을 지우고 새로운 코드로 바꾸며, 데이터 영역 역시 새로운 변수로 채워지고 새로운 코드로 바뀐다. 프로세스 제어 블록의 경우 프로세스 구분자나 PPID, CPID, 메모리 관련 사항 등은 변하지 않지만 기존의 프로세스와 다른 새로운 내용을 수행하는 프로세스가 될 것이므로 프로그램 카운터 레지스터 값을 비롯한 각종 레지스터와 사용한 파일 정보들이 리셋된다.

 exec() 시스템 호출을 사용하는 이유는 프로세스의 구조체를 재활용하기 위함이며, 이 경우 프로세스 제어 블록과 메모리 영역, 부모-자식 관계를 그대로 사용할 수 있어 편리하다.

exec() 시스템 호출

 

4. 스레드의 개념

 스레드는 프로세스의 코드에 정의된 절차에 따라 CPU에 작업 요청을 하는 실행 단위이다. (운영체제 입장에서의 작업 단위는 프로세스, CPU 입장에서의 작업 단위는 스레드)

 멀티스레드는 프로세스 내 작업을 여러 개의 스레드로 분할하여 작업의 부담을 줄이는 프로세스 기법인데, 이는 멀티태스킹(시분할 시스템)의 단점을 보완한다.

 

4. 멀티 스레드와 멀티 태스킹

 fork() 시스템 호출로 프로세스를 복사하면 불필요한 정적 영역이 중복되어 생성된다. 이 문제를 해결하기 위해 하나의 프로세스 내에 여러 개의 스레드를 생성하는 것이 멀티 스레드이다. 멀티 스레드는 코드, 파일 등의 자원을 공유하여 자원의 낭비를 막는다. 즉 두 개의 프로세스를 만드는 대신 코드와 데이터 등을 공유하며 여러 개의 일을 하나의 프로세스에서 수행하는 것이다.

멀티 태스킹과 멀티 스레드의 비교

 멀티 스레드를 사용할 경우 한 스레드가 입출력으로 작업이 진행되지 않더라도 다른 스레드가 작업을 계속해서 수행하므로 작업 요구에 빨리 응답할 수 있으며, 위에서 언급했듯 불필요한 자원 낭비를 막아 시스템 효율을 높인다. 한편 멀티 스레드는 다중 CPU에 적합한데, 다중 CPU가 멀티 스레드를 동시에 처리하여 프로세스 처리 시간을 단축할 수 있기 때문이다.

+ Recent posts