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

배고픈메꾸리·2022년 2월 8일
0

운영체제

목록 보기
1/4

1. 프로세스

운영체제에서 프로세스는 하나의 작업 단위(Task)
폰노이만 구조에서 프로그램이 실행된다는 것은 메모리에 올라와서 작업이 진행되는 것. 이 때 프로그램이란 저장장치에 있는 정적인 상태이고 프로세스는 메모리에 올라온 동적인 상태임

1-1) PCB

운영체제는 프로그램을 메모리의 적당한 위치로 가져옴. 그와 동시에 PCB(Process Controll Block) 이라는 작업 지시서를 만드는데 PCB가 없으면 프로그램이 프로세스로 전환되지 못함

  • 포인터
    준비 상태와 대기 상태는 큐로 운영되는데, 큐를 구현할 때 PCB의 포인터를 사용한다.
  • 프로세스 상태
    프로세스가 현재 어떤 상태에 있는지를 나타냄
  • 프로세스 구분자
    메모리상에는 여러 프로세스가 존재하므로 이를 구분할 수 있는 PID를 저장
  • 프로그램 카운터
    다음에 실행될 명령어의 위치를 가리키는 프로그램 카운터 값을 저장함
  • 프로세스 우선순위
    프로세스의 중요도가 각각 다름. 사용자 프로세스보다 중요한 커널 프로세스는 우선순위가 높고 사용자 프로세스 끼리도 우선순위가 다르다. CPU 스케줄러가 프로세스를 우선순위 기준으로 실행 상태로 옮김
  • 레지스터 정보
    이전에 프로세스가 수행되는 동안 사용했던 값을 보관해야 작업을 이어갈 수 있으므로 해당 값들을 저장함
  • 메모리 관리 정보
    CPU는 실행하려는 프로세스가 어떤 위치에 저장되어 있는지 알아야함 이를 위해 프로세스의 위치 정보가 담겨 있으며 메모리 보호를 위한 경계 레지스터한계 레지스터도 포함되어 있음
  • 할당된 자원 정보
    프로세스를 실행하기 위해 사용되는 입출력 자원, 파일등에 관한 정보
  • PPID와 CPID
    부모 프로세스를 가리키는 PPID와 자식 프로세스를 가리키는 CPID

PCB는 프로세스를 관리하는 데이터 구조로 운영체제 영역에 만들어짐

※ 포인터의 역할
시스템 내에는 다양한 종류의 입출력 장치가 있기 때문에 대기 상태로 모이는 프로세스도 다양함. 예를 들어 하드디스크로부터 인터럽트가 들어왔는데 프로세스가 한 곳에 모여있으면 해당 프로세스를 찾기위해서 모든 프로세스를 뒤져야함. 이러한 불편함을 해결하기 위해서 같은 입출력을 요구한 프로세스끼리 모아놓음

1-2) 프로세스의 상태


(* 준비상태 -> 실행상태)

  • 생성 상태
    프로세스가 메모리에 올라와 실행 준비를 완료한 상태. 프로세스를 관리하는 데 필요한 PCB가 생성됨
  • 준비 상태
    생성된 프로세스가 CPU를 얻을 때까지 기다리는 상태
  • 실행 상태
    준비 상태에 있던 프로세스가 CPU를 얻어 실제 작업을 수행하는 단계
  • 완료 상태
    작업을 마치고 PCB를 제거한 상태

준비 상태에 있던 프로세스 중 다음에 실행할 프로세스를 선정하는 일은 CPU 스케줄러가 담당함. CPU 스케줄러는 준비 상태의 맨 앞에서 기다리고 있는 PCB를 CPU에 전달하여 작업이 이루어지도록 함. 이 때 준비 상태의 프로세스 중 하나를 골라 실행 상태로 바꾸는 작업을 디스패치 라고 함


(* 준비상태 -> 실행상태)

오늘날의 운영체제는 효율성을 고려하여 한 가지 상태를 더 만들었음. 프로세스가 입출력을 요구하면 CPU가 직접 데이터를 가져오지 않고 입출력 관리자에게 명령을 내리게 되는데 입출력 요청은 컴퓨터의 연산속도에 비하면 굉장한 시간을 낭비하는 것이기 때문에 프로세스의 입출력이 완료될 때까지 기다리는 대기 상태가 추가됨.

대기 상태의 프로세스는 요청한 입출력이 완료되면 입출력 관리자로부터 인터럽트를 받음. 이 때 대기 상태가 종료된 프로세스는 실행 상태로 가지 않고 준비 상태로 돌아감


(* 준비상태 -> 실행상태)

보류 상태는 프로세스가 메모리에서 잠시 쫓겨난 상태로 대부분 컴퓨터의 성능을 저하시키거나 실행을 미루어도 큰 지장이 없는 프로세스임. 보류 상태는 보류 대기 상태보류 준비 상태 로 구분되며 보류 상태에 들어간 프로세스는 메모리 밖으로 쫓겨나 스왑 영역에 보관됨. 추가적으로 메모리밖으로 쫓겨나지 않고 멈춘 상태를 휴식 상태 라고 함.

1-3) 문맥 교환(Context Switching)

문맥 교환은 CPU를 차지하던 프로세스가 나가고 새로운 프로세스를 받아들이는 작업을 말함

1-4) 프로세스의 구조

프로세스는 코드 영역, 데이터 영역, 스택 영역 으로 구성됨.

데이터 영역은 추가로 일반 데이터 영역과 힙 영역으로 나뉜다.

  • 코드 영역
    코드 영역은 프로그램의 본문이 기술된 곳으로 텍스트 영역이라고도 함. 우리가 작성하는 코드가 코드 영역에 읽기 전용으로 처리됨

  • 데이터 영역
    데이터 영역은 코드가 실행되면서 사용하는 변수 , 파일 등 각종 데이터를 모아놓은 곳. 데이터는 변하는 값이기 때문에 해당 영역은 기본적으로 읽기와 쓰기가 가능함 (상수 영역은 읽기만 가능하다)

  • 스택 영역
    스택 영역은 운영체제가 프로세스를 실행하기 위해 부수적으로 필요한 데이터를 모아놓은 곳. 예를 들어 함수를 호출하면 원래 프로그램으로 돌아올 위치를 해당 영역에 저장함

1-5) 프로세스의 생성과 복사

프로세스를 생성할 때, 매번 새로 생성하는 방법뿐 아니라 기존의 프로세스를 복사하는 방법도 있음

fork 시스템 호출의 개념

fork()는 실행중인 프로세스로 부터 새로운 프로세스를 복사하는 함수임. 만약 인터넷 브라우저를 켜 놓은 상태로 Ctrl + N 단축키를 실행하면 현재의 브라우저 프로그램을 fork로 복사하여 실행됨

fork를 통하여 프로세스를 복사하면 원래 프로세스는 부모 프로세스, 새로 생긴 프로세스는 자식 프로세스가 된다.

fork의 동작 과정

fork를 호출하면 PCB를 포함한 부모 프로세스 영역이 대부분 자식 프로세스에 복사되어 같은 프로세스가 만들어진다. 다만 일부 내용은 부모 프로세스와 다르게 변경된다.

  • PID가 바뀜 위 그림에서 부모 프로세스는 PID가 326 , 자식 프로세스는 PID가 368 인 것을 확인 가능

  • 메모리 관련 정보가 바뀜. 부모 프로세스와 자식 프로세스가 존재하는 메모리 위치가 다르기 때문

  • PPID와 CPID가 바뀜. 부모 프로세스에서는 자식 프로세스를 가리키는 CPID가 368로 , 자식 프로세스에서는 부모 프로세스를 가리키는 PPID가 326으로 바뀌며 추가적으로 자식 프로세스의 CPID는 -1임.

fork의 장점

  • 프로세스 생성 속도가 빠름
    하드디스크로 부터 가져오는 것이 아니기 때문에 빠름
  • 추가 작업 없이 자원 할당 가능
    부모 프로세스가 파일 A를 사용하기 위해 초기화 하였다면 자식 프로세스에서는 초기화 하지 않고 바로 사용 가능함
  • 시스템 관리를 효율적으로 가능
    프로세스가 종료될 때 프로세스가 사용하던 자원(메모리 , 파일 , 하드웨어 등) 을 정리해야 하는데, 이러한 정리를 부모 프로세스에게 맡김으로써 효율적으로 관리 가능

exec 시스템 호출의 개념

exec() 시스템 호출은 기존의 프로세스를 새로운 프로세스로 전환하는 함수.
exec를 사용하는 목적은 프로세스의 구조체를 재활용하기 위함임. 새로운 프로세스를 만들려면 PCB를 만들고 메모리의 자리를 확보해야 하는데 exec를 사용하면 새로운 코드 영역만 가져오면 되기 때문에 기존 프로세스의 PCB , 메모리 영역 , 부모-자식 관계를 그대로 사용 가능함

exec의 동작 과정

exec를 호출하면 코드 영역에 있는 기존의 내용을 지우고 새로운 코드로 바꾼다. 추가적으로 PCB에서 PID , PPID , CPID , 메모리 관련 사항은 변하지 않지만 프로그램 카운터, 각종 레지스터 , 파일 정보가 전부 리셋됨

1-6) 프로세스의 계층 구조

유닉스에서 커널이 처음 메모리에 올라와 부팅되면 커널 관련 프로세스를 여러개 만드는데 그 중 init 프로세스는 모든 프로세스의 출발점이 됨.

init 프로세스는 일반 프로세스 맨 위에 위치하며, fork와 exec를 이용하여 자식 프로세스를 만든다.

프로세스 계층 구조의 장점

계층 구조는 동시에 여러 작업을 처리하고 종료된 프로세스의 자원을 회수하는데 유용함

  • 여러 작업 동시 처리
    login 프로세스는 인증을 거쳐 컴퓨터에 접속하는 과정을 처리함. 예를 들어 사용자 3명이 동시에 컴퓨터에 접속한다면 동시에 3명을 처리해야 하는데, login 프로세스는 1명만 처리 가능함. 이 때 fork를 활용하여 login 프로세스를 여러 개 만들어 사용자에게 나누어 주면 새로운 사용자가 들어올 때마다 작업을 동시에 처리 가능

    login 프로세스를 통과하고 나면 shell 프로세스가 필요하다. shell이 있어야만 사용자가 운영체제에 명령을 내리고 결과를 얻을 수 있다. login 프로세스가 작업을 마치면 메모리 공간이 비워지고 PCB가 제거되며, shell 프로세스를 위한 메모리 공간이 확보되고 PCB도 새로 생성됨 하지만. 이러한 작업은 굉장히 비효율적이므로 exec 호출을 사용하여 login 프로세스를 shell 프로세스로 전환시킴

  • 용이한 자원 회수
    프로세스가 독립적으로 만들어지면 프로세스가 종료될 때마다 자원을 회수하러 가야하는데, 모든 프로세스를 부모-자식 관계로 만들면 자식프로세스가 작업을 마쳤을 때 사용하던 자원을 부모가 회수하는 방식으로 간결화 할 수 있다.

고아 프로세스
부모 프로세스는 자원을 회수하기 위해 자식 프로세스가 끝날 때 까지 기다려야 함. 그런데 부모 프로세스가 먼저 종료되거나 자식 프로세스가 비 정상적으로 종료되면 종료 후에도 사용하던 자원이 그대로 남아 있는데 이러한 프로세스를 고아 프로세스라고 함

2. 스레드

운영체제는 코드와 데이터를 메모리에 가져와 PCB를 생성하고 프로세스를 준비 큐에 대기시킴. 프로세스가 생성되면 CPU 스케줄러는 프로세스가 해야 할 일을 CPU에 전달하고 CPU는 작업을 수행함. 이 때 CPU 스케줄러가 CPU에 전달하는 일 하나를 스레드라고 함.

스레드
프로세스의 코드에 정의된 절차에 따라 CPU에 작업 요청을 하는 실행 단위

2-1) 스레드 관련 용어

  • 멀티 스레드
    멀티스레드는 프로세스 내 작업을 여러 개의 스레드로 분할함으로써 작업의 부담을 줄임

  • 멀티태스킹
    멀티태스킹은 운영체제가 CPU에 작업을 줄 때 시간을 잘게 나누어 배분하는 기법(시분할 시스템)

  • 멀티프로세싱
    멀티프로세싱은 CPU를 여러개 사용하여 여러 개의 스레드를 동시에 처리하는 작업 환경. 하나의 컴퓨터에 여러 개의 CPU 혹은 하나의 CPU에 여러 개의 코어에 스레드를 배정하는 방식

  • CPU 멀티스레드
    한번에 하나씩 처리해야 하는 스레드를 파이프라인 기법을 이용하여 여러 스레드를 처리하도록 만든 병렬 처리 기법

멀티스레드 vs CPU 멀티스레드
멀티스레드: 운영체제가 소프트웨어적으로 프로세스를 작은 단위의 스레드로 분할하여 운영
CPU 멀티스레드 : 하드웨어적인 설계를 통해 CPU에서 여러 스레드를 동시에 처리하는 병렬 처리 기법

2-2) 멀티스레드의 구조와 예시

보통의 프로그래밍 언어는 순차적으로 실행되기 때문에 여러 개의 작업을 동시에 처리하기 위하여 fork나 exec를 사용하였음. 그러나 fork는 낭비적인 요소가 많은데 코드 영역과 데이터 영역의 일부가 메모리에 중복되어 존재함.

스레드는 이러한 멀티태스킹의 낭비 요소를 제거하기 위해 사용함. 비슷한 일을 하는 2개의 프로세스를 만들어 메모리 공간을 낭비하는 대신 코드 , 데이터를 공유하면서 여러 개의 일을 프로세스 내에서 처리함

왼쪽 그림처럼 fork를 호출하여 여러 개의 프로세스를 만들면 중복되는 정적 영역이 많아짐. 이처럼 한 프로세스내에서 여러 스레드를 생성하는 멀티스레드는 자원의 낭비를 막는 효과가 있음

2-3) 멀티스레드의 장단점

장점


비디오 플레이어 프로세스를 예로 들어서 이해해보자. 일반적으로 비디오 플레이어는 재생할 파일을 저장장치로부터 가져오는 입출력 부분과 데이터를 화면에 렌더링하는 부분으로 나뉨. 이러한 기능을 단일 스레드로 구현하면 입출력을 요청한 프로세스는 입출력이 끝날 때까지 대기 상태로 전환됨. 하지만 멀티스레드로 구현한다면 입출력 스레드가 대기상태에 있더라도 재생 스레드는 실행가능함.

멀티스레드의 장점은 다음과 같이 요약할 수 있음

  • 응답성 향상
    한 스레드가 다른 작업을 수행중이더라도 다른 스레드가 사용자의 작업 요구에 응답가능

  • 자원 공유
    프로세스가 가진 자원을 공유하게 되어 작업을 원할하게 진행 가능

  • 효율성 향상
    멀티스레드는 불필요한 자원의 중복을 막음으로써 시스템 효율 향상

  • 다중 CPU 지원
    2개 이상의 CPU를 가진 컴퓨터에서 멀티스레드를 사용하면 다중 CPU가 멀티스레드를 동시에 처리하여 프로세스의 처리 시간이 단축됨

단점

멀티스레드에는 단점도 있는데 자원을 공유하기 때문에 하나의 스레드에 문제가 생기면 전체 프로세스에 영향을 미칠 수 있기 때문임. 스레드를 공부하며 대표적으로 많이 듣는 예시인 브라우저를 예로 들어 설명하면 멀티스레드로 구현된 IE에서는 하나의 탭에서 문제를 일으키면 프로세스 전체가 종료되는 경우가 많음. 크롬의 경우 하나의 탭을 독립적인 프로세스로 설계하여 다른 프로세스에 미치는 영향이 상대적으로 적음. 과거와 달리 요즘은 메모리가 넉넉하고 멀티코어 CPU가 대중화되어 여러 개의 프로세스를 CPU에서 동시에 실행하는데 큰 무리가 없기 때문

2-4) 멀티스레드 모델

프로세스는 커널 프로세스사용자 프로세스로 나뉘며 스레드에도 커널 스레드사용자 스레드가 있음

  • 커널 스레드 : 커널이 직접 생성하고 관리하는 스레드
  • 사용자 스레드 : 라이브러리에 의해 구현된 일반적인 스레드

사용자 스레드가 커널 스레드를 사용하려면 시스템 호출로 커널 기능을 이용해야함. 이떄 커널 스레드와 사용자 스레드의 대응 방식에 따라 다음과 같이 분류함

사용자 스레드

사용자 스레드는 운영체제가 멀티스레드를 지원하지 않을 때 사용하는 방법임. 이 스레드는 사용자 레벨에서 스레드를 구현하기 때문에 관련 라이브러리를 사용하여 구현하며, 라이브러리가 커널이 지원하는 스케줄링이나 동기화 같은 기능을 대신 구현해줌(커널 입장에서 해당 스레드는 하나의 프로세스처럼 보임). 사용자 프로세스 내에서 여러 개의 스레드가 존재하지만 커널의 스레드 하나와 연결되기 때문에 1 to N 모델이라고 부름

사용자 스레드는 라이브러리가 직접 스케줄링하고 처리하기 때문에 문맥 교환이 필요 없음 사용자 스레드는 같은 브라우저에서 탭을 나누는 수준의 작업이기 때문에 문맥 교환 없이 적절한 값만 저장하고 복귀시키면 되기 때문임

사용자 스레드의 단점은 여러 개의 스레드가 하나의 커널 스레드와 연결되기 때문에 커널 스레드가 대기 상태에 들어가면 모든 사용자 스레드가 같이 대기하게 됨 ( 커널 스레드 입장에서는 하나의 프로세스이기 때문에 개별 관리가 불가능) 또한 타임 슬라이스를 여러 스레드가 공유하기 때문에 여러 CPU를 동시에 사용할 수 없음. 마지막으로 보안에 취약한데 커널 레벨에서는 공유 변수를 보호하는 장치가 있으나 이러한 서비스를 제공받지 못하기 때문

커널 스레드

커널 스레드는 커널이 멀티스레드를 지원하는 방식으로 하나의 사용자 스레드가 하나의 커널 스레드와 연결되기 때문에 1 to 1 모델 이라고 부름

장단점은 사용자 스레드와 정반대임. 커널 스레드는 커널 레벨에서 모든 작업을 지원하기 때문에 멀티 CPU를 지원하고 하나의 스레드가 대기 상태에 있어도 다른 스레드는 작업을 계속할 수 있다. 또한 커널의 기능을 사용하므로 보안에 강하고 안정적으로 작동함. 하지만 문맥 교환시 오버헤드 때문에 느리게 작동함

멀티레벨 스레드

사용자 스레드와 커널 스레드를 혼합한 방식으로 M to N 모델 이라고 부름

멀티레벨 스레드는 사용자 스레드와 커널 스레드의 장단점을 모두 갖고 있음. 하나의 커널 스레드가 대기 상태에 들어가면 다른 커널 스레드가 유연하게 작업을 처리 가능함. 하지만 마찬가지로 문맥 교환시 오버헤드가 있어 사용자 스레드만큼 빠르지는 않음. 따라서 빠르게 움직여야 하는 스레드는 사용자 스레드로, 안정적으로 움직여야 하는 스레드는 커널 스레드로 작동함

profile
FE 개발자가 되자

0개의 댓글