philosophers 개념정리

이민규·2023년 7월 30일
0

42seoul

목록 보기
20/24

스레드

스레드의 개념

스레드란 하나의 프로세스 내에서 동시에 진행되는 작업 갈래, 흐름의 단위 를 의미한다 우리가 하나의 프로세스 예를들어 인터넷을 열었을때 웹서핑도 하면서 파일도 받고 동영상도 볼 수 있는 것이 스레드를 이용해서 여러가지 작업을 동시에 진행되기 때문이다 이러한 작업 흐름을 스레드 라고 하며 스레드가 여러개 존재한다면 이를 멀티(다중)스레드 라고 부른다

프로세스의 자원구조

  • 코드 영역 (text / code) : 프로그래머가 작성한 코드가 CPU가 해석 가능한 기계어로 변환되어 저장되어져 있다
  • 데이터 영역 (data) : 코드가 실행되면서 사용되는 전역변수나 각종 데이터들이 모여져있다 데이터 영역은 3가지로 세분화된다
    • .data : 전역 변수나 static변수 등 프로그램이 사용하는 데이터를 저장된다
    • .BSS : 초기값이 없는 전역변수나 static변수가 저장된다
    • .rodata : const같은 상수 키워드로 선언 된 변수나 문자열 상수가 저장된다
  • 스택 영역(stack) : 지역 변수와 같은 호출한 함수가 종료될 때 돌아올 임시 자료를 저장하는 공간이다 stack은 함수의 호출과 함께 할당되며 함수의 호출이 완료되면 소멸한다
  • 힙 영역 (heap) : 생성자, 인스턴스, malloc같은 동적으로 할당된는 데이터들을 위해 존저해는 공간이다 사용자에 의해 메모리가 동적으로 할당되고 해제된다

코드 영역과 데이터 영역은 선언할 때 크기가 결정되는 정적 영역이지만 스택 영역과 힙 영역은 프로세스가 실행되는 동안 크기가 늘어났다가 줄어드는 동적 영역이다

스레드의 자원 공유

한 프로세스안의 스레드들은 프로세스의 자원을 공유함으로서 실행 속도가 빠르게 동작될 수 있다 이때 Code, Data, Heap영역은 스레드끼리 공유 되지만 stack영역은 각각의 스레드 마다 별도의 stack을 가지고있게된다stack을 고유하게 가지고 있다는 뜻은 stack은 함수 호출 시 전달되는 인자 되돌아갈 주소값 함수 내에서 선언하는 변수 등을 저장하는 메모리 공간이기 때문에 독립적인 실행흐름을 가질 수 잇다는 말이다


스레드의 동시실행 원리

코어와 스레드

컴퓨터를 구매해본적이 잇다면 CPU를 구매할때 코어와 쓰레드라는 말을 들어보았을 것이다 이 때 코어란 물리적으로 명령어를 메모리에서 읽어와 실행하는 반도체 유닛을 의미하고 스레드는 논리적인 코어 갯수를 의미한다 사진의 cpu는 6코어 12스레드로 하나의 코어당 스레드 두개 이상을 동시에 실행 시킬 수 있어 운영체제가 12개의 작업을동시에 처리할 수 있다는 것을 의미한다
우리가 컴퓨터를 이용할때는 프로그램을 12개 이상으로 많이 열고 사용할텐데 어떻게 12개의 스레드로 동작시키는 것일까 이는 병렬성과 동시성이라는 개념으로 설명을 할 수 있다

병렬성 (Parallelism)

병렬성은 말 그대로 명령어를 cpu의 코어와 스레드 수에 맞춰서 여러가지 작업을 병렬로 동시에 수행하는 것을 말한다 듀얼코어 쿼드코어 옥타코어 등 해당 명칭이 붙는 멀티코어 프로세서가 달린 컴퓨터에서 할 수 있는 방식이다

동시성 (Concurrency)

동시성은 둘 이상의 작업이 동시에 실행되는 것을 의미한다 이 때 병렬성에서 말하는 동시가 물리적으로 실제로 동시에 실행한다는 것을 의미하면 동시성에서 동시는 동시에 실행하는 것 처럼 보이게 하는 것으로 이해하면 된다 예를들어 1개의 코어가 있고 4개의 작업이 있다가 가정한다면 4개의 작업을 번갈아가면서 매우 빠르게 처리하기 동시에 동작하는 것 처럼 보이게 된다 이와같이 진행중인 작업을 번걸아가면서 바꾸는 행위를 Context Switching이라고 부른다 동시성이 필요한 이유

  • 하드웨어적 한계 : CPU에 코어를 많이 넣어도 8개 16개가 많이 들어가는건데 보통 PC를 사용하면서 동시에 사용되는 프로세스는 훨씬 많긴때문에 동시성이 필요하다
  • 논리적인 효율 : 예를 들어 4코어 8스레드의 CPU환경에서 16개의작업이 존재하는데 8개의 작업은 빠른 시간안에 끝나고 8개의 작업은 장시간이 소요되는 작업이라고 가정할 때 최대 8개까지 동시실행이 가능한데 장시간 소요되는 동작이 8개 쓰레드를 점유하고있으면 나머지 짧은 시간만 있으면 되는 8개의 동작들이 장시간 소요되는 작업이 끝날때까지 대기를 해야되는 문제가 발생한다 이러한 점을 극복하기 위해 작업을 잘게 나눠 번갈아가면서 처리하는 동시성 개념을 채택한 것이다

스케줄링(Scheduling)

스케줄링이란 이처럼 여러가지 프로세스나 스레드들이 동시성을 가지고 동작을 진행할 때 운영체제에서 CPU를 상용할 수 있는 작업을 선택하고 CPU를 할당하는 작업을 말한다 스케줄링은 우선순위, 작업량 등을 고려하여 효율적으로 배치하며 이를 통해 운영체제는 CPU를 효율적으로 사용한다

프로세스 상태

프로세스는 생성되어 실행되는 동안 여러가지 상태를 가지게 되고 상태의 변화에 따라 프로세스가 동작된다 일반적으로 프로세스는 5가지 상태를 가지고 있다

프로세스 상태설명
생성 (new)프로세스가 생성되고 아직 준비가 되지 않은 상태
준비 (ready)프로세스가 실행을 위해 기다리는 상태 CPU를 할당받을 수 있는 상태이며 언제든지 실행할 준비가 되어있다
실행 (run)프로세스가 CPU를 할당받아 실행되는 상태
대기 (waiting)프로세스가 특정 이벤트(입출력 요청 등)가 발생하여 대기하는 상태 CPU를 할당받지 못하며 이벤트가 발생하여 다시 READY 상태로 전환 될 때까지 대기한다
종료 (terminated)프로세스가 실행을 완료하고 종료된 상태 더 이상 실행될 수 없으며 메모리에서 제거되게 된다

프로세스 상태 전이

프로세스 상태 전이란 프로세스가 실행되는 동안 상태가 OS에 의해 변경되는 것을 말한다 운영체제는 프로세스의 상태를 감시하고 프로세스 상태와 프로세스 스케줄링을 통하여 프로세스를 관리하고 제어한다

  • Admitted (new -> ready) : 프로세스 생성을 승인 받음
  • Dispatch (ready -> running) : 준비 상태에 있는 여러 프로세스들 중 하나가 스케줄러에 의해 실행됨
  • Interrupt (running -> ready) : 예기치 않은 이벤트가 발생하여 현재 실행중인 프로세스를 준비 상태로 전환하고 해당작업을 먼저 처리합니다
인터럽트 유형발생 원인 및 역할
타이머 인터럽트미리 설정된 시간 경과 시 발생합니다
하드웨어 인터럽트하드웨어 장치에서 발생한 이벤트로 예를들어 디스크 I/O 작업 완료 등의 이벤트가 있습니다
소프트웨어 인터럽트프로세스 내부에서 발생한 이벤트로 특정 상황이나 조건에 발동됩니다
입출력 인터럽트입출력 장치에서 발생한 작업완료나 데이터 도착과 같은 이벤트에 발동됩니다
예외 인터럽트프로세스가 비정상적인 동작을 하거나 잘못된 명령을 실행하면 발동됩니다
  • I/O or event wait (running -> waiting) : 실행 중인 프로세스가 입출력이나 이벤트를 처리해야 하는 경우 입출력이나 이벤트가 끝날 때까지 대기 상태로 전환
  • I/O or event completion (waiting -> ready) : 입출력이나 이벤트가 모두 끝난 프로세스를 다시 준비 상태로 만들어 스케줄러에 선택될 수 있는 상태로 전환

프로세스 컨텍스트 스위칭

컨텍스트 스위칭(Context Switching)은 현재 cpu에서 동작중인 프로세스를 다른 프로세스로 전환하는 과정을 의미한다 동시성파트에서 보았듯이 CPU는 여러 개의 프로세스를 번갈아가며 실행하는데 이 때 CPU활용률을 높이기 위해 컨텍스트 스위칭이 필요하다
1. 동작중인 프로세스가 대기를 하며 현재 프로세스의 상태(Context)를 보관한다
2. 대기중인 다음 순서의 프로세스가 동작하면서 이전에 보관되어져있던 자신의 프로세스 상태를 복구한다
이 때 다음 프로세스는 스케줄러가 결정하게 된다

PCB(Process Control Block)

PCB(프로세스 제어 블록)은 운영체제에서 프로세스를 관리하기위한 상태정보를 담고있는 자료구조를 의미한다 프로세스를 컨텍스트 스위칭 할때 기존에 작업하던 상태를 이어서 할 수 있는것이 PCB를 바탕으로 이루어진다=-

  • Pointer(포인터) : 프로세스의 현재 위치를 저장하는 포인터 정보
  • Process state(프로세스 상태) : 프로세스의 상태 (생성, 준비, 실행, 대기, 종료)를 저장
  • 프로세스 ID (Process ID, PID) : 프로세스만의 고유한 ID
    프로그램 카운터 (Program counter) : 프로세스를 위해 실행될 다음 명령어의 주소를 포함하는 카운터를 저장
  • 레지스터 (Register) : 누산기, 베이스, 레지스터 및 범용 레저스터를 포함하는 CPU 레지스터에 있는 정보
  • 메모리 제한 (Memory Limits) : 운영체제에서 관리하는 메모리 관리 시스템에 대한 정보
  • Accounting : 프로세스의 리소스 사용 및 성능에 관련된 정보 (cpu시간 및 사용량, 스케줄링 및 우선순위 정보 등)
  • 열린 파일 목록 (List of open file) : 프로세스를 위해 열린 파일 목록

Context Switching Overhead

Context Switching과정은 사용자로 하여금 빠른 반응성과 동시성을 제공하지만 실행되는 프로세스를 변경하는 과정(프로세스의 상태, 레지스터 값 저장 불러오기 등)에서 시스템에 부하를 주게 된다
Context Switching Overhead 이유

  • PCB 저장 및 복원 비용
  • CPU 캐시 메모리 무효화에 따른 비용
  • 프로세스 스케줄링 비용

스레드 상태

스레드는 일반적으로 4가지 상태를 가진다

스레드 상태설명
NEW스레드가 생성되고 아직 호출되지 않은 상태
RUNNABLE스레드가 실행되기 위해 기다리는 상태 CPU를 할당받을 수 있는 상태이며 언제든지 실행될 준비가 된 상태이다
BLOCKED스레드가 특정 이벤트(입출력 요청 등)가 발생하여 대기하는 상태 CPU를 할당받지 못하며 이벤트가 발생하여 다시 RUNNABLE상태로 전환될 때까지 대기한다
TERMINATED스레드가 실행을 완료하고 종료된 상태 더 이상 실행될 수 없으며 메모리에서 제거된다

스레드 컨텍스트 스위칭

스레드 컨텍스트 스위칭(thread context switching)은 멀티 스레드 환경에서 스레드 간의 실행을 전환하는 기술이다 스레드 컨테스트 스위칭은 하나의 프로세스 안에 있는 스레드들끼리 교환이 이루어진다

TCP(Thread Control Block)

PCB처럼 스레드도 TCB(Thread Control Block)을 가지고 있는데 TCB는 PCB안에 포함되어있다 스레드 ID, 스레드 우선순위, 스케줄링 정보 등을 포함하고 있으며 스레드 간의 자원 공유와 동기화도 TCB를 이용하여 관리된다 뮤텍스나 세마포어 같은 동기화 기법을 사용하면 TCB내에서 해당 스레드의 뮤텍스타 세마포어 정보를 관리하고 스레드가 해당 자원에 대한 접근 권한을 획득하거나 반납할 때 TCB의 정보를 업데이트 하게 한다

프로세스 컨텍스트 스위칭 vs 스레드 컨텍스트 스위칭

프로세스 컨텍스트 스위칭과 스레드 컨텍스트 스위칭은 모두 멀티태스킹 환경에서 여러 프로세스 또는 스레드를 동시에 실행하기 위한 기술이지만 몇가지 차이점이 있다

  • TCB가 PCB보다 가볍다 : 프로세스 내의 스레드들은 text, data, heap 영역의 메모리를 공유하기 때문에 TCB에는 stack 및 간단한 register 포인터 정보만을 저장하게되서 PCB 보다 TCB가 가벼워 더 빨리 읽고 쓸 수 있다 따라서 스레드 컨텍스트 스위칭이 프로세스 컨텍스트 스위칭보다 더 빠르다
  • 캐시 메모리 초기화 여부 : CPU의 캐시 메모리는 CPU와 메인 메모리 사이에 위치하며 CPU에서 한번 이상 읽어온 메모리의 데이터를 저장해놓고 그 데이터를 다시 필요로 할때 메모리를 통하지않고 곧바로 데이터를 전달해준다 그러나 프로세스 컨텍스트 스위칭이 일어날 경우 cpu캐시 메모리를 초기화 해야 되기 때문에 부담이 된다 스레드 컨텍스트 스위칭의 경우 스택과 레저스터 값 등 일부 정보면 변경되므로 CPU 캐시 메모리가 초기화되지 않는다
  • 자원 동기화 문제 : 스레드 컨텍스트 스위칭이 발생할 때 공유 데이터에 접근을 하게 될 경우 우리가 원하는 동작과 다른 동작이 이루어질 수 있다 이와같은 상황을 경쟁조건 (race condition)이라고 한다

데이터 레이스(data race)

데이터 레이스란 멀티 스레드/프로세스 환경에서 공유자원에 동시에 접근할 때 일어나는 경쟁 상황을 의미한다 예를 들어 두개의 스레드가 동시에 한 변수값을 한 스레드는 일고 한 스레드는 쓰려고 할 때 데이터레이스가 발생한다

<데이터레이스가 발생하는 예시>
공유 변수 sharedVariable 초기값 0

스레드 1:
    반복 10000:
        sharedVariable 값을 읽어옴
        sharedVariable에 1을 더함
        sharedVariable 값을 저장

스레드 2:
    반복 10000:
        sharedVariable 값을 읽어옴
        sharedVariable에 1을 더함
        sharedVariable 값을 저장

모든 스레드 종료 대기

최종 sharedVariable 값 출력

이러한 데이터 레이스를 해결하기 위한 방법으로 상호배제라는 기법이 있다 공유자원을 모든 쓰레드/프로세스가 원하는 때 언제든지 접근할 수 있도록 허용하지 않고 제한적으로 허용하는 방식이다 상호배제를 이용하는 기법에는 뮤텍스 락, 세마포아 락 등이 존재한다

임계구역(Critical Section)

Critical Section은 병렬프로그래밍에서 둘 이상의 스레드가 동시에 접근해서는 안되는 공유 자원 (파일, 입출력, 공유 데이터)을 접근하는 명령문 또는 코드의 일부 영역을 의미합니다 병렬프로그래밍에서 임계구역을 값을 동시에 읽고 쓰는 동작을 수행하면 읽는 시점이 변경된 값인지 변경되기 전 값인지 예측할 수 없어 이를 해결하기 위해 동기화 기법을 사용하여야 한다

mutex lock

mutex란 mutual exclusion(상호배제)의 약자로 임계구역의 동시 접근 문제를 해결하기 위한 방법 중 하나입니다
화장실 열쇠가 하나가 있고 화장실을 갈려면 열쇠가 필요하면 화장실을 가고싶은 사람들은 기존에 화장실을 간 사람이 돌아와서 열쇠를 반납하기 까지 기달려야 할 것입니다 이처럼 임계구역에 하나의 스레드만이 접근할 수 있게 하는 방법을 mutex lock이라고 합니다

semapore lock

세마포어 락(semapore lock)이란 mutex lock과는 다르게 하나 이상의 스레드가 공유 자원에 접근하도록 할 수 있습니다

화장실 안에 변기가 세칸이 있다면 기달리는 사람은 세칸중에 한칸이라도 비어있으면 들어갈 수 있을 것입니다 이처럼 세마포어의 값 만큼 임계구역에 접근할 수 있게하는 방법을 세마포어락 이라고 합니다

mutex lock vs semapore lock

mutex locksemapore lock
사용 목적단일 리소스에 대한 상호 배제여러 리소스를 동시에 관리하거나 한정된 개수의 스레드만 동시에 접근 할 수 있게 제어
값의 의미0 또는 1 값을 가지고 있으며 0은 잠금상태(사용중) 1은 해제상태를 의미합니다세마포어는 초기값을 가지며 해당 값 만큼 스레드가 동시 접근 가능합니다 스레드가 접근할때마다 값이 줄어들며 0이하인 경우에는 스레드가 대기해야합니다
unlock방식lock을 건 스레드만 unlock이 가능합니다lock을 걸지않은 스레드도 signal을 이용해서 unlock이 가능합니다

교착상태 (Dead lock)

교착상태(Dead lock)은 상호배제에 의해 나타나는 문제점으로 두 개 이상의 작업이 서로 상대방의 자원을 필요로 하여 작업이 끝나기만을 기다리고 있기 때문에 결과적으로 아무것도 완료되지 못하는 상태이다

교착 상태의 발생 조건 (모두 성립해야 발생)설명
상호 배제하나의 프로세스가 자원을 사용중일 때 다른 프로세스는 그를 사용할 수 없다
점유 대기최소 하나의 자원을 점유하고 있으면서 다른 프로세스가 사용중인 자원을 추가로 점유하기 위해 대기하는 프로세스가 존재한다
비선점다른 프로세스가 자원을 사용중인 경우 그 사용이 끝날 때 까지 강제로 뺏을 수 없다
순환대기프로세스 간의 자원 요청이 원형으로 연결되어 순환 형태의 대기 상태가 형성되어야 한다 예를 들어 프로세스 A는 프로세스 B가 점유한 자원을 필요로 하고 프로세스 B는 프로세스 C가 점유한 자원을 필요로 하며 프로세스 C는 프로세스 A가 점유한 자원을 필요하 하는 식입니다

교착상태를 없에는 방법

예방기법 : 예방기법은 교착상태가 발생하지 않도록 교착상태 발생의 네가지 조건 중에서 하나를 제거하는 방법입니다

  • 상호 배제 부정 : 한번에 여러개의 프로세스가 공유자원을 사용할 수 있도록 합니다
  • 점유 및 대기 부정 : 프로세스가 실행되기 전 필요한 모든 자원을 할당하여 프로세스 대기를 없에거나 자원이 점유되지 않은 상태에서만 자원을 요구하도록 합니다
  • 비선점 부정 : 자원을 점유하고 있는 프로세스가 다른 자원을 요구할 때 점유하고 있는 자원을 반납하고 요구한 자원을 사용하기 위해 기다리게 합니다
  • 순환 대기 부정 : 자원을 선형 순서로 분류하여 고유번호를 할당하고 각 프로세스는 현재 점유한 자원의 고유번호보다 앞이나 뒤 어느 한쪽으로만 자원을 요구하도록 합니다

회피기법 : 회피기법은 교착상태가 발생할 가능성을 배제하지 않고 교착상태가 발생하면 적절히 피해나가는 방법으로 대표적으로 은행원 알고리즘을 사용합니다

발견기법 : 발견기법은 시스탬이 교착상태가 발생했는지 점검하여 교착상태에 있는 프로세스와 자원을 발견하는 방법입니다 교착상태 발견 알고리즘과 자원 할당 그래프 등을 사용할 수 있습니다

회복기법 : 회복기법은 교착상태를 일으킨 프로세스를 종료하거나 교착상태의 프로세스에 할당된 자원을 선점하여 프로세스나 자원을 회복하는 것을 의미합니다

  • 프로세스 종료 : 교착상태에 있는 프로세스를 종료하는 것으로 교착상태에 있는 모든 프로세스를 종료하는 방법과 하나씩 종료해나가면서 교착상태를 해결하는 방법이 있습니다
  • 자원선점 : 교착상태의 프로세스가 점유하고 있는 자원을 선점하여 다른 프로세스에게 할당하며 해당 프로세스를 일시 정지시키는 방법입니다

기아상태 (Starvation)

기아상태란 특정 프로세스의 우선순위기 낮아서 원하는 자원을 계속해서 할당 받지 못하는 상태를 의미합니다 기아상태를 해결하기 위해서는 우선순위를 수시로 변경하거나 오래기다린 프로세스의 우선순위를 높이는 등 스케줄링관련 조치가 필요합니다

profile
프로그래머 희망자(휴직중)

1개의 댓글

comment-user-thumbnail
2023년 7월 30일

좋은 글 감사합니다.

답글 달기