본문 바로가기
  • 1+1=3
개발인강

[운영체제] 프로세스와 쓰레드

by 여스 2021. 12. 31.
반응형

강의: 비전공자를 위한 운영체제(인프런)

프로그램과 프로세스

- 프로그램

하드디스크와 같은 저장장치에 저장된 명령문의 집합체를 말함. 애플리케이션이나 앱이라고도 불림. windows운영체제에선 .exe 모습을 하고 있음

 

- 프로세스

실행중인 프로그램. 즉, 하드디스크에 있는 프로그램이 메모리(ram)에 올라갔을 때 프로세스라고 불림.

 

코드영역: 자신을 실행하는 코드가 저장됨.

데이터영역: 전역변수와 정적변수 저장됨.

스택영역: 지역변수와 함수호출관련 정보.

힙영역: 프로그래머가 동적으로 메모리 할당시 사용.

 

 

 

 

 

프로그램은 컴퓨터의 관점에서 하드디스크(저장장치)만 사용하는 수동적인 존재임. 반면 프로세스는 메모리도 사용하고, 운영체제의 cpu스케쥴링 알고리즘에 따라서 cpu도 사용하고 필요에 따라 입려과 출력을 하기에 능동적인 존재임.

 

- 소스코드가 프로그램이 되는 과정(c언어기준)

.c -> 전처리기 -> .i -> 컴파일러 -> .s ->어셈블러 -> .o -> 링커 -> .exe

 

위 .exe프로그램을 더블클릭하면 메모리에 올라가서 프로세스가 되는것임. 프로세스는 이제 운영체제에 의해 관리됨.

 

멀티프로그래밍과 멀티프로세싱

- 유니프로그래밍

메모리에 오직 하나의 프로세스가 올라온 것

 

- 멀티프로그래밍

메모리에 여러개의 프로세스가 올라온 것

 

위 두개는 메모리의 관점에서 본 것이고,

아래는 cpu관점에서 본 것

 

- 멀티프로세싱

cpu가 여러개의 프로세스를 처리하는 것. 오늘날엔 멀티프로그래밍과 멀티프로세싱이 공존함. cpu가 시분할처리를 이용해서 멀티프로세싱을 함.

 

PCB(Process Controll Block)

운영체제는 메모리에 올라온 프로세스들을 공평하게 실행시켜야 함.

프로세스가 만들어지면 운영체제는 해당 프로세스의 정보를 가지고 있는 PCB(Process Control Block)을 만들고 저장함. pcb들은 링크드리스트 자료구조로 저장됨. 운영체제는 프로세스가 종료되면 링크드리스트에서 해당 프로세스의 pcb를 제거함.

 

-구조:

포인터: 부모와 자식 프로세스에 대한 포인터 등

프로세스 상태: 생성, 준비, 실행, 대기, 완료를 나타냄.

프로세스 id: 식별숫자

프로그램 카운터: cpu가 시분할처리를 하는데 잠깐 다른거 처리하고 돌아올때 어디까지 했는지 기억하는 용도.

레지스터 정보: 이것도 프로그램카운터처럼 cpu가 다른거하고 올때 기억하기 위한 용도.

메모리 관련 정보: 프로세스가 메모리에 있는 위치정보 등

cpu 스케쥴링 정보: cpu스케쥴링에 필요한 우선순위, 최종실행시간, cpu점유시간 등

등등등

 

프로세스 상태

- 생성상태(new)

pcb를 생성하고 메모리에 적재를 요청한 상태. 메모리에 프로그램적재를 승인받으면 준비상태로 넘어감.

 

- 준비상태(ready)

cpu를 사용하기 위해 기다리고 있는 상태. cpu스케쥴러에 의해 cpu가 할당됨. 대부분의 프로세스는 이 준비상태에 있음.

 

- 실행상태(running)

준비상태에 있는 프로세스가 cpu스케쥴러에 의해 cpu를 할당받아 실행되는 상태. 실행상태에 있는 프로세스의 수는 cpu의 개수만큼임. cpu가 한개라면 실행상태의 프로세스는 최대 한 개이다. 실행상태에 있는 프로세스도 cpu를 무한정 쓸 수 있는게 아니라 부여된 시간만큼만 사용가능함.(cpu스케쥴러가 할당된 시간지나면 cpu강제로 빼앗음). cpu 뺏기면 다시 준비상태로 돌아간다.

 

- 대기상태(waiting)

프로세스가 입출력 요청을 하면 입출력 완료될때까지 기다리는 상태. 매우 빠른 cpu에 비해 입출력은 매우 느리므로 대입출력하는동안 cpu기다리는 건 매우 비효율적이므로, 대기상태로 두고 다른 프로세스에 cpu를 할당함. 그러다 입출력작업 완료되면 대기상태에 있는 프로세스에게 cpu할당 기회를 줌. 

 

- 완료상태(terminated)

프로세스가 종료된 상태. 프로세스가 사용했던 데이터를 메모리에서 제거하고 생성된 pcb도 제거.

 

컨텍스트 스위칭

프로세스를 실행하는 중에 다른 프로세스를 실행하기 위해 실행중인 프로세스의 상태를 저장하고 다른 프로세스의 상태값으로 교체하는 작업. 컨텍스트 스위칭이 일어날 때 pcb의 내용이 변경됨. 실행중인 프로세스의 작업내용을 pcb에 저장하고, 실행될 기존프로세스의 pcb의 내용대로 cpu가 다시 세팅됨. 

발생상황예시)

프로세스 a가 실행을 하고 있는데 cpu점유시관 초과 - 운영체제가 인터럽트 발생시킴 - 프로세스 a는 하던일 멈추고, 나중에 다시 시작해야하니까 현재 cpu의 레지스터 값 등을 pcb a에다가 저장 - 이제 pcb b를 참조해서 이전 프로세스 b의 상태로 cpu레지스터값 설정 - 이제 프로세스 b가 점유시간동안 cpu 사용 - ---반복

 

컨텍스트 스위칭이 발생하는 경우:

cpu 점유시간 다되거나, I/O요청이 있거나, 다른 종류의 인터럽트가 있을 때임.

 

프로세스 생성과 종료

- .exe 파일 더블클릭

-> 운영체제가 해당프로그램의 코드영역과 데이터 영역을 메모리에 로드 빈(empty) 스택과 빈 힙을 만들어 공간확보

-> 이 프로세스를 관리하기 위한 pcb만들어서 값도 초기화

 

그러나 위처럼 새로 생성하는 방식은 운영체제가 부팅되고 0번프로세스가 부팅될 때 딱 한번만 실행됨. 이제부터 나머지 프로세스는 새로 생성하지 않고 복사해서 사용함. (fork()함수 이용). 새로 생성하는 것보다 복사하는게 더 빠르기 때문. 0번프로세스는 부모프로세스, 복사하는 애들은 자식프로세스라고 함.

자식프로세스는 부모 프로세스의 코드영역, 데이터영역, 스택영역과 pcb내용 전부 복사함. 복사(fork()) 후 exec()함수를 쓰면 복사한 영역을 원하는 값으로 덮어쓰므로 부모프로세스와 완전 다르게 동작함.

부모프로세스는 자식프로세스의 Exit Status를 읽고 자식프로세스를 정리함. 근데 만약 부모프로세스가 먼저 정리되거나, 자식프로세스가 비정상적으로 종료되서 Exit Status를 읽지 못해서 메모리에 계속 살아있으면 좀비 프로세스라고 부름.(보통 컴터 오래켜두면 메모리가 많아지고, 좀비프로세스도 많아져서 느려지는것임)

 

쓰레드

프로세스가 많아지면 그 수만큼 pcb, 코드영역, 데이터영역, 스택영역, 힙영역도 만들어줘야 하는데, 너무 무거워짐. 즉 프로세스는 메모리를 많이 먹는다. 따라서 쓰레드 탄생. 

쓰레드는 프로세스 내에 1개 이상이 있을 수 있음. 한 프로세스 내의 쓰레드들은 그 프로세스의 pcb, 코드영역, 데이터영역, 힙영역을 공유함.(스택은 공유안하고 스레드마다 가짐). 프로세스 내애 쓰레드가 여러개 있을 수 있으니 쓰레드 구분해야 하니까, 쓰레드 id 부여하고 TCB(Thread Controll Block)도 생김. 

이제 운영체제가 프로세스를 구분할 수 있으니 운영체제가 작업을 처리하는 단위는 프로세스 내의 쓰레드임.

 

ex) 

파이어팍스 브라우저를 하나 키면 프로세스 하나 탄생

브라우저 탭 하나를 더 키면 프로세스가 생기는 게 아니라, 쓰레드가 하나 더 생김. 탭 10개 생성하면 하나의 프로세스에 쓰레드가 10개 생김.( 사실 파이어팍스는 탭 4개까지는 프로세스 새로생기긴 함..ㅋㅋ)

->메모리 절약된다!!

 

프로세스와 쓰레드 장단점

-안정성

프로세스는 서로 독립적이기 때문에 하나가 잘못되도 다른게 영향받지 않는다.(안정성 굿)

반면 쓰레드는 하나의 프로세스 내에 존재하기 때문에 프로세스 하나 문제생기면 안에있는 모든 쓰레드도 영향받음.(안정성 배드)

 

-속도와 자원

프로세스는 서로 각각의 자원(pcb, 코드, 데이터, 힙, 스택)을 가지고 있기때문에 서로 통신하려면 IPC통신을 해야 해서 오버헤드가 크고 속도가 느림. 

반면 프로세스는 하나의 프로세스에서 스택만 빼고 모든 자원을 공유하기 때문에 오버헤드가 굉장히 작음. 단, 쓰레드 간의 통신은 데이터 공유되니까 쉽게 가능하지만 공유되는 공간에서 문제 생길 수 있음(프로세스 동기화 관련...)

반응형

댓글