운영체제(Operating System) - 3

Mins·2023년 4월 18일
0
post-thumbnail

프로세스와 스레드

부셔버리자


프로세스의 개요

프로세스의 개념

프로그램

  • 저장장치에 저장되어 있는 정적인 상태

프로세스

  • 실행을 위해 메모리에 올라온 동적인 상태

프로그램에서 프로세스로의 전환

프로세스 제어 블록

  • 프로세스 제어 블록 (PCB Process Controll Block)은 프로그램이 프로세스로 전환될 때 운영체제가 만드는 작업 지시서
  • 어떤 프로그램이 프로세스가 되었다는 것은 운영체제로부터 프로ㅔㅅ스 제어 블록을 받았다는 의미
  • 프로세스 제어 블록에 있는 대표적인 세 가지 정보
    • 프로세스 구분자 (Process IDentification; PID) : 각 프로세스를 구분하는구분자
    • 메모리 관련 정보 : 프로세스의 메모리 위치 정보, 메모리 보호를 위한 경계 레지스터와 한계 레지스터
    • 각종 중간값 : 프로세스가 사용했던 중간값

프로그램이 프로세스가 되는 과정

프로세스와 프로그램의 관계

  • 프로그램이 프로세스가 된다는 것은 운영체제로부터 제어 블록을 얻는다는 뜻
  • 프로세스가 종료된다는 것은 해당 프로세스 제어 블록이 폐기된다는 뜻

    프로세스=프로그램+프로세스제어블록프로세스 = 프로그램 + 프로세스 제어 블록
    프로그램=프로세스프로세스제어블록프로그램 = 프로세스 - 프로세스 제어 블록

프로세스의 네 가지 상태

  • 생성 상태 (create status) : 프로세스가 메모리에 올라와 실행 준비를 완료한 상태. 프로세스 제어 블록 생성
  • 준비 상태 (ready status) : 생성된 프로세스가 CPU를 얻을 때까지 기다리는 상태
  • 실행 상태 (running status) : 준비 상태에 있는 프로세스 중 하나가 CPU를 얻어 실제 작업을 수행하는 상태
  • 완료 상태 (terminate status) : 실행 상태의 프로세스가 주어진 시간 동안 작업을 마치면 진입하는 상태. 프로세스 제어 블록 사라짐.

  • CPU 스케줄러 (CPU scheduler) : 준비 상태에 있는 여러 프로세스 중 다음에 실행할 프로세스를 선정
  • 디스패치 (dispatch) : 준비 상태의 프로세스 중 하나를 골라 실행 상태로 바꾸는 CPU 스케줄러의 작업
  • 타임아웃 (time out) : 프로세스가 자신에게 주어진 하나의 타임 슬라이스 동안 작업을 끝내지 못해 다시 준비 상태로 돌아가는 것

프로세스의 다섯 가지 상태

  • 대기 상태 (blocking status) : 실행 상태의 프로세스가 입출력을 요청하면 입출력이 완료될 때까지 기다리는 상태로 작업 효율을 높이기 위해 만들어진 것

프로세스의 상태 정리

상태설명
생성 상태저장장치에 저장된 프로그램이 메모리로 올라와 실행되어 프로세스가 되는 상태로 커널 영역에 프로세스 제어블록이 만들어진다. 생성된 후에는 준비상태로 이동한다.
준비 상태실행을 기다리는 모든 프로세스가 준비 큐에서 자기 차례를 기다리는 상태다. 실행될 프로세스를 CPU 스케줄러가 선택한다.
실행 상태선택된 프로세스가 타임 슬라이스를 얻어 CPU를 사용하는 상태다. 작업을 마치면 완료 상태로 가고 작업을 끝내지 못하면 준비 상태로 되돌아간다.
대기 상태실행 상태에 있는 프로세스가 입출력을 요청하면 입출력이 완료될 때까지 기다리는 상태다. 입출력이 완료되면 준비상태로 이동한다.
완료 상태프로세스가 종료된 상태다. 사용하던 모든 자원은 반납되고, 메모리에서 지워지며, 프로세스 제어 블록은 폐기된다.

휴식 상태와 보류 상태

  • 휴식 상태 (pause status) : 프로세스가 작업을 일시적으로 쉬고 있는 상태
  • 보류 상태 (suspend status) : 프로세스가 메모리에서 잠시 쫓겨난 상태로 '일시 정지 상태'라고도 불림
    • 메모리가 꽉 차서 일부 프로세스를 메모리 밖으로 내보낼 때
    • 프로그램에 오류가 있어서 실행을 미루어야 할 때
    • 바이러스와 같이 악의적인 공격을 하는 프로세스라고 판단 될 때
    • 매우 긴 주기로 반복되는 프로세스라 메모리 밖으로 쫓아내도 큰 문제가 없을 때
    • 입출력을 기다리는 프로세스의 입출력이 계속 지연될 때

보류 상태를 포함한 프로세스의 상태

프로세스 제어 블록과 문맥 교환

프로세스 제어 블록

프로세스 제어 블록 (PCB)

  • 프로세스를 실행하는 데 필요한 중요한 정보를 보관하는 자료구조
  • 프로세스는 고유의 프로세스 제어 블록을 가짐
  • 프로세스 생성 시 만들어져서 프로세스가 실행을 완료하면 폐기

프로세스 제어 블록의 구성 (1)

  • 포인터 : 준비 상태나 대기 상태의 큐를 구현할 때 사용
  • 프로세스 상태 : 프로세스가 현재 어떤 상태에 있는지를 나타내는 정보
  • 프로세스 구분자 : 운영체제 내에 있는 여러 프로세스를 구현하기 위한 구분자
  • 프로그램 카운터 : 다음에 실행될 명령어의 위치를 가리키는 프로그램 카운터의 값
  • 프로세스 우선순위 : 프로세스의 실행 순서를 결정하는 우선순위
  • 각종 레지스터 정보 : 프로세스가 실행되는 중에 사용하던 레지스터의 값

프로세스 제어 블록의 구성 (2)

  • 메모리 관리 정보 : 프로세스가 메모리의 어디에 있는지 나타내는 메모리 위치 정보, 메모리 보호를 위해 사용하는 경계 레지스터 값과 한계 레지스터 값 등
  • 할당된 자원 정보 : 프로세스를 실행하기 위해 사용하는 입출력 자원이나 오픈 파일 등에 대한 정보
  • 계정 정보 : 계정 번호, CPU 할당 시간, CPU 사용 시간 등
  • 부모 프로세스 구분자와 자식 프로세스 구분자 : 부모 프로세스를 가리키는 PPID와 자식 프로세스를 가리키는 CPID 정보

문맥 교환

  • 문맥 교환은 CPU를 차지하던 프로세스가 나가고 새로운 프로세스를 받아들이는 것
  • 두 프로세스의 프로세스 제어 블록을 교환하는 작업

문맥 교환의 절차

문맥 교환과 타임 슬라이스의 크기

  • 타임 슬라이스는 되도록 작게 설정하되 문맥 교환에 걸리는 시간을 고려하여 적당한 크기로 설정하는 것이 중요

프로세스의 연산

프로세스의 구조

프로세스의 구조

코드 영역

  • 프로그램의 본문이 기술된 곳
  • 프로그래머가 작성한 코드가 탑재되며 탑재된 코드는 읽기 전용으로 처리됨

데이터 영역

  • 코드가 실행되면서 사용하는 변수나 파일 등의 각종 데이터를 모아놓은 곳
  • 데이터는 변하는 값이므로 이곳의 내용은 기본적으로 읽기와 쓰기가 가능

스택 영역

  • 운영체제가 프로세스를 실행하기 위해 필요한 데이터를 모아놓은 곳
  • 프로세스 내에서 함수를 호출하면 함수를 수행하고 원래 프로그램으로 되돌아 올 위치를 저장하는 곳
  • 운영체제가 사용자 프로세스를 작동하기 위해 유지하는 영역으로 사용자에게는 보이지 않음

프로세스의 생성과 복사

fork() 시스템 호출의 개념

  • 실행 중인 프로세스로부터 새로운 프로세스를 복사하는 함수
  • 실행 중인 프로세스와 똑같은 프로세스가 하나 더만들어짐

    fork() 시스템 호출은 실행 중인 프로세스를 복사하는 함수다. 이때 실행하던 프로세스는 부모 프로세스, 새로 생긴 프로세스는 자식 프로세스로서 둘은 부모- 자식 관계가 된다.

fork() 시스템 호출의 동작 과정

  • fork() 시스템 호출을 하면 프로세스 제어 블록을 포함한 부모 프로세스 영역의 대부분이 자식 프로세스에 복사되어 똑같은 프로세스가 만들어짐
  • 단, 프로세스 제어 블록의 내용 중 다음이 변경됨
    • 프로세스 구분자 (PID)
    • 메모리 관련 정보
    • 부모 프로세스 구분자 (PPID)와 자식 프로세스 구분자 (CPID)

fork() 시스템 호출의 장점

  • 프로세스의 생성 속도가 빠름
  • 추가 작업 없이 자원을 상속할 수 있음
  • 시스템 관리를 효율적으로 할 수 있음

fork() 시스템 호출의 예 (1)

  • 부모 프로세스의 코드가 실행되어 fork() 문을 만나면 똑같은 내용의 자식 프로세스를 하나 생성
  • 이때 fork() 문은 부모 프로세스에 0보다 큰 값을 반환하고 자식 프로세스에 0을 반환
  • 만약 0보다 작은 값을 반환하면 자식 프로세스가 생성되지 않은 것으로 여겨 'Error'를 출력

fork() 시스템 호출의 예 (2)

  • 부모 프로세스의 코드가 실행되어 fork() 문을 만나면 똑같은 내용의 자식 프로세스 생성
  • fork() 문은 부모 프로세스에 0보다 큰 값을 반환하고 자식 프로세스에 0을 반환
  • 0보다 작은 값을 반환하면 자식 프로세스가 생성되지 않은 것으로 여겨 'Error' 출력

exec() 시스템 호출의 개념

  • 기존의 프로세스를 새로운 프로세스로 전환 (재사용) 하는 함수
    • fork() : 새로운 프로세스를 복사하는 시스템 호출
    • exec() : 프로세스는 그대로 둔 채 내용만 바꾸는 시스템 호출

    exec() 시스템 호출은 이미 만들어진 프로세스의 구조를 재활용하는 것이다.

exec() 시스템 호출의 동작 과정

  • exec() 시스템 호출을 하면 코드 영역에 있는 기존의 내용을 지우고 새로운 코드로 바꿔버림
  • 데이터 영역이 새로운 변수로 채워지고 스택 영역이 리셋
  • 프로세스 제어 블록의 내용 중 프로세스 구분자, 부모 프로세스 구분자, 자식 프로세스 구분자, 메모리 관련 사항 등은 변하지 않지만 프로그램 카운터 레지스터 값을 비롯한 각종 레지스터와 사용한 파일 정보가 모두 리셋

exec() 시스템 호출의 예

  • 부모 프로세스 fork() 문을 실행하여 자식 프로세스를 생성하고, wait() 문을 실행하여 자식 프로세스가 끝날 때 까지 기다림
  • 새로 생성된 자식 프로세스는 부모 프로세스의 코드와 같음
  • exec() 시스템 호출을 사용하여 새로운 프로세스로 전환하더라도 프로세스 제어 블록의 각종 프로세스 구분자 (PID, PPID, CPID)가 변경되지 않기 때문에, 프로세스가 종료된 후 부모 프로세스로 돌아올 수 있음

프로세스의 계층 구조

유닉스의 프로세스 계층 구조

  • 유닉스의 모든 프로세스는 init 프로세스의 자식이 되어 트리 구조를 이룸

프로세스 계층 구조의 장점

  • 여러작업을 동시에 처리할 수 있다.
  • 프로세스의 재사용이 용이하다.
  • 자원회수가 쉽다
    • 프로세스를 계층 구조로 만들면 프로세스 간의 책임 관계가 분명해져서 시스템을 관리하기가 수월

고아 프로세스와 좀비 프로세스

  • 고아 프로세스 (orphan process)는 부모 프로세스가 먼저 종료되어 돌아갈 곳이 없는 프로세스
  • 좀비 프로세스 (zombie process)는 자식 프로세스가 종료되었는데도 부모 프로세스가 뒤처리를 하지 않아 발생하는 프로세스
  • C 언어에서는 exit() 또는 return() 문을 사용해 자식 프로세스의 작업이 끝났음을 부모 프로세스에 알림

스레드

스레드의 개념

스레드의 정의

  • CPU 스케줄러가 CPU에 전달하는 일 하나
  • CPU가 처리하는 작업의 단위는 프로세스로부터 전달받은 스레드
    • 운영체제 입장에서의 작업 단위는 프로세스
    • CPU 입장에서의 작업 단위는 스레드

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

프로세스와 스레드의 차이

  • 프로세스끼리는 약하게 연결되어 있는 반면 스레드끼리는 강하게 연결

스레드 관련 용어

  • 멀티스레드 : 프로세스 내 작업을 여러 개의 스레드로 분할해 작업 부담을 줄이는 프로세스 운영 기법
  • 멀티태스킹 : 운영체제가 CPU에 작업을 줄 때 시간을 잘게 나누어 배분하는 기법
  • 멀티 프로세싱 : 여러 개 CPU로 여러 개 스레드를 동시에 처리하는 작업 환경
  • CPU 멀티스레드 : 한 번에 하나씩 처리해야 하는 스레드를 잘게 쪼개어 동시에 처리하는 명령어 병렬 처리 기법

멀티스레드의 구조와 예

멀티스레드의 구조

멀티스레드 장단점

멀티스레드의 장점

  • 응답성 향상
  • 자원 공유
  • 효율성 향상
  • 다중 CPU 지원

멀티스레드의 단점

  • 모든 스레드가 자원을 공유하기 때문에 한 스레드에 문제가 생기면 전체 프로세스에 영향을 미침
  • 인터넷 익스플로러에서 여러 개의 화면을 동시에 띄웠는데 그 중 하나에 문제가 생기면 인터넷 익스플로러 전체가 종료

멀티스레드 모델

커널 스레드와 사용자 스레드

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

사용자 스레드 ( 1 to N 모델 )

  • 사용자 프로세스 내에 여러 개의 스레드가 커널의 스레드 하나와 연결 (1 to N 모델)
  • 라이브러리가 직접 스케줄링을 하고 작업에 필요한 정보를 처리하기 때문에 문맥 교환이 필요 없음
  • 커널 스레드가 입출력 작업을 위해 대기 상태에 들어가면 모든 사용자 스레드가 같이 대기하게 됨
  • 한 프로세스의 타임 슬라이스를 여러 스레드가 공유하기 때문에 여러 개의 CPU를 동시에 사용할 수 없음

커널 스레드 ( 1 to 1 모델 )

  • 하나의 사용자 스레드가 하나의 커널 스레드와 연결 (1 to 1 모델)
  • 독립적으로 스케줄링이 되므로 특정 스레드가 대기 상태에 들어가도 다른 스레드는 작업을 계속할 수 있음
  • 커널 레벨에서 모든 작업을 지원하기 때문에 멀티 CPU를 사용할 수 있음
  • 하나의 스레드가 대기 상태에 있어도 다른 스레드는 작업을 계속 할 수 있음
  • 커널의 기능을 사용하므로 보안에 강하고 안정적으로 작동
  • 문맥 교환할 때 오버헤드 때문에 느리게 작동

커널 스레드 1 to 1 모델 - 독립적인 관리

멀티레벨 스레드 ( M to N 모델 )

  • 사용자 스레드커널 스레드를 혼합한 방식 (M to N 모델)
  • 커널 스레드가 대기 상태에 들어가면 다른 커널 스레드가 대신 작업을 하여 사용자 스레드보다 유연하게 작업을 처리할 수 있음
  • 커널 스레드를 같이 사용하기 때문에 여전히 문맥 교환 시 오버헤드가 있어 사용자 스레드 만큼 빠르지 않음
  • 빠르게 움직여야 하는 스레드는 사용자 스레드로 작동하고, 안정적으로 움직여야 하는 스레드는 커널 스레드로 작동

동적 할당 영역과 시스템 호출

프로세스의 동적 할당 영역

프로세스의 구조

  • 코드 영역 : 프로그램의 본체가 있는 곳
  • 데이터 영역 : 프로그램이 사용하려고 정의한 변수와 데이터가 있는 곳
  • 스택 영역과 힙 영역 : 프로세스가 실행되는 동안 만들어지는 영역으로 크기가 늘어났다 줄어들기도 하는 동적 할당 영역

스택 영역

  • 스레드가 작동하는 동안 추가되거나 삭제되는 동적 할당 영역
  • 스레드가 진행됨에 따라 커지기도 하고 작아지기도 함

힙 영역

  • 프로그램이 실행되는 동안 할당되는 변수 영역
  • 포인터, malloc() 함수, calloc()함수 등은 메모리를 효율적으로 사용하기 위해 만들어진 것으로 어쩌다 한 번 쓰는 큰 배열을 처음부터 선언하고 끝까지 놔두는 일이 없어야 함 \rarr free(); 로 더이상 쓰지 않음)

exit() 와 wait() 시스템 호출

exit() 시스템 호출

  • 작업의 종료를 알려주는 시스템 호출
  • exit() 함수를 선언함으로서 부모 프로세스는 자식 프로세스가 사용하던 자원을 빨리 거둬 갈 수 있음
  • exit() 함수는 전달하는 인자를 확인하여 자식 프로세스가 어떤 상태로 종료되었는지를 알려주는데, 인자가 0이면 정상 종료이고 -1이면 비정상 종료

wait() 시스템 호출

  • 자식 프로세스가 끝나기를 기다렸다가 자식 프로세스가 종료되면 다음 문장을 실행하는 시스템 호출
  • 부모 프로세스와 자식 프로세스 간 동기화에도 사용

wait() 함수의 응용

  • 전면 프로세스에서는 셸이 wait() 함수를 사용하기 때문에 자식 프로세스가 끝날 때까지 다음 명령어를 입력받을 수 없음
  • 후면 프로세스에서는 셸이 wait() 함수를 사용하지 않기 때문에 다음 명령어를 받아들일 수 있음
0101sleep 100전면 프로세스
0202sleep 100&전면 프로세스

& 을 사용함으로서 강제적으로 후면으로 지정

profile
민성 개발블로그

0개의 댓글