-
운영체제의 프로세스운영체제 2020. 10. 19. 12:52728x90
프로세스
프로세스는 디스크에 저장되어 있는 실행 파일이 실행되어 메모리에 올라오면 이를 프로세스라 함
프로세스의 메모리
-
Text : 코드
-
Stack : 지역변수, 파라미터
-
Data : 전역변수, static 변수
-
Heap : 동적할당
프로세스의 상태
-
new : 프로스세스가 갓 생성됨
-
running : Instruction(명령어)가 실행 중임
-
waiting : 대기 중
-
ready : 프로세서에 할당되기를 기다리는 중
-
terminated : 프로세스가 실행을 마침
PCB(Process Control Block)
OS가 프로세스를 관리하기 위한 자료구조로, 프로세스 1개당 PCB 1개가 할당
PCB를 Task Control block 이라고도 부름
하드웨어와 프로세스의 맵핑을 용이하게 하기 위해 필요함
구성 요소
-
Process state : Running, waiting 등 프로세스의 상태
-
Process number : PID
-
Program counter : 현재 프로세스가 실행해야할 다음 instruction의 주소
-
Registers : CPU의 레지스터에 저장되었던 값들
-
Memory limits : 프로세스에 할당된 메모리
-
List of open files
-
CPU 스케쥴링 정보 : 우선순위, 스케쥴링 큐 포인터
-
Accounting(통계) 정보 : CPU 사용량, clock time, 시작 시간 등
-
I/O 상태 정보 : I/O 디바이스, 파일 등
메인 메모리에 저장된 대부분의 PCB 들은 현재 실행 중이지 않고 대기 중이며 Interrupt 를 받거나 System call 이 생겨 현재 실행 중인 프로세스가 Context switching 되어야 한다면 나중에 다시 실행되기 위해 해당 프로세스는 자신의 상태정보들을 PCB에 저장해둠. 이후 CPU를 점유하게될 프로세스를 os 가 결정했다면 그 프로세스의 PCB에 저장된 상태정보들을 레지스터에 로딩함
프로세스 스케쥴링
CPU utilization(활용도)를 최대화시키기 위해 필요한 작업
Process scheduler : CPU를 다음번에 사용할 프로세스를 선택하는 자
스케쥴링을 위해 필요한 여러 큐
-
Job queue : 시스템에 존재하는 모든 프로세스
-
Ready queue : 메모리에 올라온 모든 프로세스로 ready, waiting to execute : 언제든 동작 가능
-
Device queue : I/O device를 기다리는 프로세스로, I/O device 마다 하나의 device queue를 가짐
프로세스 생성 시 ready queue 에 놓이고, 스케쥴러에게 선택(dispatch) 될 때까지 ready queue에서 기다림
프로세스에게 CPU가 할당되면 아래 Event 가 발생할 때까지 CPU에서 실행됨
-
입출력 요청을 하여 I/O queue 에 넣어짐
-
자식 프로세스를 생성하고, 자식 프로세스의 종료를 기다림
-
인터럽트(timer event) 발생을 기다림
-
할당된 시간 간격이 만료됨
스케쥴러의 종류
Short-term scheduler (CPU scheduler) : 다음에 실행될 프로세스를 고르고, CPU에 할당해주는 스케쥴러
Long-term scheduler (Job scheduler) : Ready 큐에 프로세스를 넣거나 빼는 스케쥴러
Good mix of processes : Ready 큐에 I/O bound process, CPU-bound process가 적절히 섞여야 cpu 활용도가 높아짐
Medium-term scheduler : 프로세스가 너무 많아 스케쥴링에 지장이 있을 때 swapping 하는 스케쥴러
swapping
swap out : 메모리가 부족하다거나 하는 이유로 스케쥴링이 어려울 때 프로세스를 다시 디스크로 돌려보내는 것
swap in : swap out 되었던 프로세스를 다시 ready queue로 불러들이는 것
I/O bound process : I/O 하는 시간이 긴 프로세스
CPU-bound process : 계산하는 시간이 긴 프로세스
Context Switch
실행 중인 프로세스를 바꾸는 작업 : 아무래도 오버헤드가 있기 때문에 너무 많이 하는것도 문제임
프로세스의 Context 는 PCB 안에 저장되어 있음
프로세스 생성
부모 프로세스가 자식 프로세스를 생성하며 이들은 서로 트리관계를 가짐
-
리소스 공유 옵션
-
부모와 자식이 모든 리소스를 공유함 : Code(Text) 공간은 완전히 공유
-
자식이 부모의 일부를 공유
-
전혀 공유하지 않음
-
실행 옵션
-
부모와 자식이 동시에 실행됨
-
부모가 자식이 종료되기까지 대기
pid = 1인 프로세스를 init 프로세스 혹은 systemd 프로세스라 함
프로세스 생성 과정
-
실행 바이너리 파일을 로더가 메모리로 로딩함
-
Runtime stack 영역 할당
-
Heap 영역 할당
-
I/O 설정 : 기본적으로 표준입출력, 에러 파일 3개가 할당됨
-
이후 LTS, STS 에 의해 ready queue 에 들어갔다가 실행됨
fork() 하게되면 pid, ppid 를 제외한 나머지 부분은 부모와 자식이 완전히 동일한 메모리를 가짐
부모 프로세스가 wait(&status) 함수를 호출하면 자식이 exit() 즉 terminate 될 때까지 기다림
프로세스의 종료
child 프로세스 스스로가 exit() 을 호출한 경우
부모 프로세스가 자식프로세스를 죽이기 위해 abort() 함수를 호출한 경우
부모 프로세스가 종료되진 않았지만 wait() 함수 등을 통해 자식 프로세스의 종료상태를 회수하지 않는 경우 자식 프로세스를 좀비 프로세스라 함
부모 프로세스가 자식 프로세스보다 먼저 죽은 경우 자식 프로세스는 orphan(고아) 프로세스라 함
IPC (Interprocess Communication)
프로세스는 Cooperating 프로세스와 Independent 프로세스로 나뉨
Cooperating process
-
정보 공유
-
계산 속도 개선
-
모듈화
이러한 프로세스는 IPC를 통해 다른 프로세스와 통신하는 것이 중요함
IPC 두 가지 모델
-
Message passing
-
공유하고자 하는 정보를 메시지 큐에 메시지로서 넣어두고 대상 프로세스가 꺼내어 읽는 방식
-
Action
-
send(message)
-
receive(message)
-
Communication link 를 미리 맺어야함
-
Physical
-
Shared memory
-
Hardware bus
-
Network
-
Logical
-
Direct vs Indirect
-
Synchronous vs Asynchronous
-
Automatic vs Explicit buffering
-
윈도우에서는 LPC(Local Procedure Call) 방식으로, 서버 프로세스가 Client/Server Communication port 를 생성하여 해당 포트간의 통신으로 IPC를 제공
-
Shared memory
-
여러 프로세스가 메모리 특정 공간을 공유해두고, 공유하고자 하는 정보를 공유 메모리에 적음
-
장점 : 구현이 편함
-
단점 : 동기화 문제가 발생
-
Bounded buffer : 고정된 버퍼 사이즈
-
Unbounded buffer : 버퍼 사이즈에 제한을 두지 않음
Message passing
Direct communication
-
Action
-
send(P, message) : P에게 전달함을 명시
-
receive(Q, message) : Q로부터 받겠다고 명시
-
Communication link
-
자동으로 링크는 맺어짐
-
1:1 통신 시에 편리함
Indirect communication
공유 메일 박스에 메시지를 넣고 빼는 방식
-
Action
-
send(A, message) : 메일박스 A에 메시지 전달
-
receive(A, message) : 메일박스 A로부터 메시지 수신
-
Communication link
-
메일박스를 공유해야 링크가 생성
-
여러 프로세스가 통신할 때 편리함
-
Operation
-
create mailbox
-
send, receive to mailbox
-
destroy mailbox
메시지를 한 개 보냈는데 나머지 두 프로세스가 모두 receive 를 요청하는 문제
해결법 (os 맘대로임)
-
두 프로세스 모두가 받아가도록 링크를 설정
-
동시에 receive() 를 호출할 수 없도록 제한
-
빨리 호출한 프로세스가 받고 송신자에게는 누가 받아갔는지 알려줌 (제일 일반적임)
Synchronous
Blocking send : 보내고 메시지가 수신될 때까지 대기
Blocking receive : 메시지가 올 때까지 대기
Asynchronous
Non-blocking send : 메시지를 보내고 제 할일 함
Non-blocking receive : 수신 요청 시 제대로된 메시지를 받으면 상관 없지만 못받으면 기다리지 않고 null을 받음
송신, 수신측이 모두 blocking 방식이면 rendezvous 가 생긴다 = 가장 확실한 통신 방법
버퍼링 방식
-
Zero capacity
버퍼가 없어서 송신자가 데이터를 보내면 반드시 수신되는 것을 기다려야함 -
Bounded capacity
제한된 크기의 버퍼. 송신자는 데이터를 보낼 때 버퍼가 가득 차 있으면 대기해야함 -
Unbounded capacity
무한한 크기의 버퍼로 하드웨어 오버헤드가 큼. 송신자는 어떠한 경우에도 대기하지 않음
Shared memory
Producer-Consumer 문제
Producer는 버퍼의 full check 이후 full 이 아니면 item 을 생산하고 공유메모리(버퍼)에 저장
Consumer 는 버퍼의 empty check 이후 empty 가 아니면 item을 버퍼를 소비
이는 circular array (원형 배열)을 통해 구현하며 배열에 in이 데이터가 들어갈 인덱스, out이 데이터를 뽑아낼 인덱스라면
-
empty : in == out
-
full : (in + 1) % BUFFER_SIZE == out
// Sender
int shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
// Receiver
int shm_fd = shm_open(name, O_RDONLY, 0666);
ftruncate(shm_fd, 4096);
void * ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);
ptr += sprintf(ptr, “hi”);
shm_unlink(name);
파이프
-
Ordinary pipe : 부모자식 관계의 프로세스일 때 사용하는 파이프
-
Producer/Consumer 스타일의 통신이 가능
-
단방향 통신임 : 양방향 통신을 위해서는 파이프가 2개 필요
-
pipe(), read(), write(), close()
-
Named pipe : 부모자식 관계가 아닌 프로세스에서도 사용 가능한 파이프
-
양방향 통신이 가능
-
여러 프로세스가 동시에 통신이 가능함
-
mkfifo(), open(), read(), write(), close()
'운영체제' 카테고리의 다른 글
[OS] 가상메모리 주소공간과 MMU (0) 2020.11.26 [OS] OS 페이징 기법 (0) 2020.10.22 [OS] 운영체제와 메모리 (0) 2020.10.22 CPU 스케쥴링 (0) 2020.10.19 운영체제 기본지식과 리눅스 (0) 2020.10.18 -