프로그램은 저장 장치에 저장되어 있는 정적인 상태,
프로세스는 실행을 위해 메모리에 올라온 동적인 상태를 말한다.
프로그램을 실행하면 프로세스가 되고 OS로부터 프로세스 제어 블록을 얻는다.
프로그램을 종료하면 해당 프로세스 제어 블록이 폐기된다.
[프로세스] = [프로그램] + [프로세스 제어 블록]
[프로그램] = [프로세스] - [프로세스 제어 블록]
PCB l 프로세스를 실행하는 데 필요한 정보를 보관하는 자료 구조
· 프로세스 생성 시 만들어지고 실행 완료 시 폐기
구성 l 포인터, 프로세스 상태, 프로세스 구분자, 프로그램 카운터(PC), 프로세스 우선순위, 각종 레지스터 정보
· 포인터: 준비, 대기 상태 큐 구현
· 프로세스 상태: 프로세스 상태 정보
· 프로세스 구분자: OS 내 여러 프로세스 구현 위한 구분자 -> PID
· 프로그램 카운터(PC): 다음 실행될 명령어 위치 가리키는 값
· 프로세스 우선순위: 프로세스 실행 순서 결정
· 각종 레지스터 정보: 프로세스 실행 중 사용하던 레지스터값(언어: 외래어는 사이시옷을 붙이어 쓰지 않는다)
· 메모리 관리 정보: 프로세스의 메모리 위치 정보, 경계 레지스터값, 한계 레지스터값 등
· 할당된 자원 정보: 입출력 자원, 오픈 파일 등 정보
· 계정 정보: 계정 번호, CPU 할당 기간 및 사용 시간 등
· 부모 프로세스 구분자와 자식 프로세스 구분자: (부모 프로세스 가리킴)PPID, (자식 프로세스 가리킴) CPID 정보
<4가지로 분류>
생성 상태 l 프로세스가 메모리에 올라와 실행 준비 완료한 상태
준비 상태 l 생성된 프로세스가 CPU를 얻을 때까지 기다리는 상태
↓ 디스패치 ↑ 타임아웃
실행 상태 l 준비 상태에 있는 프로세스 중 하나가 CPU를 얻어 실제 작업을 수행하는 상태
완료 상태 l 실행 상태의 프로세스가 주어진 시간 동안 작업을 마치면 진입하는 상태
(프로세스 제어 블록 폐기)
디스패치 l 준비 상태의 프로세스 중 하나를 골라 실행 상태로 바꾸는 CPU 스케줄러의 작업
타임아웃 l 프로세스가 자신에게 주어진 하나의 타임 슬라이스 동안 작업을 끝내지 못하면 다시 준비 상태로 돌아가는 것
<5가지로 분류>
생성 상태 l 프로그램이 메모리에 올라오고 OS로부터 PCB를 할당 받은 상태
· (프로세스가 바로 실행되는 건 아니고) 준비 상태에 자기 순서를 기다리고 PCB도 준비 상태로 옮겨진다.
준비 상태 l 실행 대기 중인 모든 프로세스가 자기 순서를 기다리는 상태
· PCB는 준비 큐에서 대기(CPU 스케줄러가 관리)
· CPU 스케줄러가 하는 일
-> 큐를 몇 개 운영할지, 여기에 있는 어떤 프로세스의 제어 블록을 실행 상태로 보낼지 결정
-> 프로세스 제어 블록 선택 작업은 Dispatch(PID) 명령으로 처리
-> Dispatchㅣ프로세스가 준비 상태 -> 실행 상태로 변경, 작업 수행
실행 상태 l 프로세스가 CPU를 할당 받아 실행되는 상태
· 프로세스가 타임 슬라이스(자신에게 주어진 시간) 동안만 작업 가능
-> 시간 모두 사용 시 Timeout(PID) 실행
-> 작업 완료 시 Exit(PID) 실행(정상 종료)
· 실행 상태에 있는 프로세스가 입출력 요청 -> CPU가 입출력 관리자, 입출력 요청 -> Block(PID) 실행
· Block(PID)ㅣ자신이 수행하는 입출력 완료 전까진 작업 진행 불가, 또 요청하면 대기 상태로 옮김
-> CPU 스케줄러가 새로운 프로세스를 실행 상태로 가져온다.
대기 상태 l 실행 상태에 있는 프로세스가 입출력을 요청하면 입출력이 완료될 때까지 기다리는 상태
· 프로세스가 입출력 요청 시 완료 전까지 대기하는 상태
· 입출력 장치별 마련된 큐에서 대기 -> 완료 시 인터럽트 발생
-> 해당 인터럽트로 깨어날 프로세스 찾는다[Wakeup(PID)]
· 이걸로 프로세스 제어 블록이 준비 상태로 이동한다.
완료 상태 l 프로세스가 종료되는 상태
· 코드, 데이터 -> 메모리 삭제, 프로세스 제어 블록 폐기
· 정상 종료: exit() 처리
코어 덤프(Core Dump) · 강제 종료 만나면 디버깅 위해 종료 직전 메모리 상태 -> 저장 장치 옮긴다.
(+)
휴식 상태 l 프로세스가 작업을 일시적으로 쉬고 있는 상태
보류 상태 l 프로세스가 메모리에서 잠시 쫓겨난 상태(비정상적 상태)
· 메모리 버퍼 오버플로우, 프로그램 오류, 악의적 공격 프로세스 등에 의해 나타나는 상태이다.
문맥 교환 l 프로세스가 나가고 새로운 프로세스 받아들이는 작업
· (실행 상태에서) 나가는 PCB가 지금까지의 작업 내용 저장
· (실행 상태에서) 들어오는 PCB 내용으로 CPU 세팅
코드 영역 l 프로그램 본문 기술된 곳
데이터 영역 l 변수, 파일 등의 각종 데이터 모은 곳(RW 가능)
스택 및 힙 영역 l OS가 프로세스 실행 위해 부수적 필요 데이터 수집한 곳, 유연성이 내재된 동적 할당 영역
· 사용자에게 비가시적
-> 스택이 메모리 침범: Stack Overflow
-> 힙이 메모리 침범: Memory Leak
스택 영역 l 스레드 작동 시 추가 혹은 삭제되는 동적 할당 영역, 스레드 진행에 따라 유연하게 변화
힙 영역 l 프로그램 실행하는 동안 할당되는 변수 영역
· 포인트, malloc(), calloc() 함수 등: 메모리 효율적 사용 목적
· 새로운 프로세스 생성, malloc() 함수 만들어 해당 큐에 삽입 가능
fork() 시스템 호출 l 실행 중인 프로세스 복사 함수
· 실행 중이던 프로세스: 부모 프로세스
· 새로 생긴 프로세스: 자식 프로세스
과정 l 호출 -> 대부분의 부모 영역 내용을 자식 영역에 복사
· 자식에서 변경: 프로세스 구분자, 메모리 관련 정보 및 프로세스 저장 위치, 부모/자식 프로세스 구분자
장점 l 빠름, 추가 작업 없이 자원 상속, 시스템 관리 효율적
예 l fork() 만나면 자식 프로세스 생성 -> 부모 프로세스에 0보다 큰 값 반환, 자식 프로세스에 0 반환
-> 0보다 작은 값 반환 시 자식 프로세스 미생성으로 여겨 Error 출력
exec() 시스템 호출 l 기존 프로세스를 새로운 프로세스로 전환(프로세스 복사가 아닌 내용만 변경)
(이미 만들어진 프로세스 구조 재활용)
과정 l 호출 -> 코드 영역에 있던 기존 내용 지움, 새로운 코드 변경 -> 데이터 영역에 새로운 변수로 채워짐, 스택 영역 리셋 -> 프로세스, 부모 프로세스, 자식 프로세스 구분자 그리고 메모리 관련 사항 불변 but PC Value 비롯한 레지스터 및 파일 정보 모두 리셋
예 l fork() 문 실행, 자식 프로세스 생성 -> wait() 문 실행, 자식 프로세스 끝날 때까지 기다림
(새로 생성된 자식 프로세스 코드 == 부모 프로세스 코드) -> execlp("mplayer","mplayer",NULL) 실행
-> 자식 프로세스 코드 영역이 mplayer 코드로 변경 및 실행
(exec 써도 PID ~ 변경 안 함 ∴ 부모 프로세스로 돌아올 수 있다)
트리 구조(모든 프로세스: Init 프로세스의 '자식')
장점 l 여러 작업을 동시에, 프로세스 재사용 용이, 자원 회수 쉬움
고아 프로세스 l 부모가 자식보다 먼저 죽는 경우
· C언어에서 exit() 혹은 return() 문을 통해 고아 프로세스 발생을 방지함.
(코드 짤 때 예의상 빼먹지 마시길)
스레드(Thread) l 프로세스의 코드에 정의된 절차에 따라 CPU에 작업 요청하는 실행 단위
· CPU 스케줄러가 CPU에 전달하는 일 하나
· CPU 작업 단위: 프로세스로부터 전달받은 스레드
(운영체제 작업 단위: 프로세스 / CPU 작업 단위: 스레드)
프로세스 vs 스레드 l
· 연결 강도: 프로세스 < 스레드
멀티태스크 l 프로세스 내 여러 개 스레드로 작업 분할, 부담 줄이는 운영 기법
멀티태스킹 l CPU 작업 전달 시 시간을 잘게 나누어 배분하는 기법
멀티프로세싱 l CPU 여러 개 사용, 여러 스레드 동시 처리 기법
멀티스레드 l OS가 SW적으로 프로세스를 작은 단위의 스레드로 분할 및 운영 기법
멀티태스크 vs 멀티스레드 l
· 멀티태스크: 여러 개의 프로세스
· 멀티스레드: 하나의 프로세스 -> [여러 개의 스레드]
CPU 멀티스레드 l HW적인 방법으로 하나의 CPU에서 여러 스레드 동시 처리하는 병렬 처리 기법
· 스레드는 한 번에 하나씩 / BUT 파이프라인 기법 이용, 동시에 여러 스레드 처리
멀티태스킹 낭비 요소 l fork() 시스템 호출 -> 코드 및 데이터 영역 일부 메모리 중복되어 존재
부모-자식 관계 but 서로 독립적 프로세스(낭비 요소 제거 불가능)
멀티태스킹 vs 멀티스레드 l
· 멀티태스킹: fork() 시스템 호출로 여러 프로세스 생성, 불필요 정적 영역 多
· 멀티스레드: 코드, 파일 자원 공유 -> 자원 낭비 prevent, 효율성 향상
멀티스레드 장단점 l (●: 장점, ○: 단점)
● 응답성 향상
● 자원 공유
● 효율성 향상
● 다중 CPU 지원
○ 모든 스레드의 자원 공유, 한 스레드 문제 -> 전체 프로세스 영향
○ IE(Internet Explorer)에서 여러 화면 동시 띄움, 문제 -> IE 전체 종료
커널 스레드 l 커널이 직접 생성 및 관리하는 스레드
사용자 스레드 l 라이브러리에 의해 구현된 일반적 스레드
exit() 시스템 호출 l 작업 종료를 알려주는 시스템 호출
· 선언함으로써 자식 프로세스 사용 자원을 부모가 빨리 거둬감
· 전달 인자 확인, 어떤 상태로 종료됐는지 알림
[0: 정상, -1: 비정상 종료]
wait() 시스템 호출 l
· 자식 프로세스 종료 시 실행하는 시스템 호출
· 부모, 자식 간 동기화에도 사용
응용 l
전면 · shell의 wait() 함수 사용, 자식 종료 전까지 다음 명령어 입력 불가(sleep 100과 같이 쓴다)
후면 · shell의 wait() 함수 사용 X, 다음 명령어 받아들일 수 있음(sleep 100&과 같이 쓴다)