Concurrency

유석현(SeokHyun Yu)·2023년 6월 14일
0

운영체제

목록 보기
11/22
post-thumbnail

1. 개요

프로그램에서 한 순간에 하나의 명령만을 실행하는(단일 PC값) 고전적인 관점에서 벗어나 멀티 쓰레드 프로그램은 하나 이상의 실행 지점(독립적으로 불러 들여지고 실행될 수 있는 여러 개의 PC값)을 가지고 있다.

멀티 쓰레드를 이해하는 방법은 각 쓰레드가 프로세스와 매우 유사하지만, 차이가 있다면 쓰레드들은 주소 공간공유하기 때문에 동일한 값에 접근할 수 있다는 것이다.

하나의 쓰레드의 상태는 프로세스의 상태와 매우 유사하다.

쓰레드는 어디서 명령어들을 불러 들일지 추적하는 프로그램 카운터(PC)와 연산을 위한 레지스터들을 가지고 있다.

만약 두 개의 쓰레드가 하나의 프로세서에서 실행 중이라면 실행하고자 하는 쓰레드(T2)는 반드시 문맥 교환(context switch)을 통해서 실행 중인 쓰레드(T1)와 교체되어야 한다.

쓰레드 간의 문맥 교환은 T1이 사용하던 레지스터들을 저장하고 T2가 사용하던 레지스터의 내용으로 복원한다는 점에서 프로세스의 문맥 교환과 유사하다.

프로세스가 문맥 교환을 할 때에 프로세스의 상태를 프로세스 제어 블럭(PCB)에 저장하듯이 프로세스의 쓰레드들의 상태를 저장하기 위해서는 하나 또는 그 이상의 쓰레드 제어 블럭(TCB)이 필요하다.

가장 큰 차이 중 하나는 프로세스의 경우와 달리 쓰레드 간의 문맥 교환에서는 주소 공간을 그대로 사용한다는 것이다.

쓰레드와 프로세스의 또 다른 차이는 스택에 있다.

고전적 프로세스 주소 공간과 같은 간단한 모델(단일 쓰레드 프로세스)에서는 스택이 하나만 존재한다.

주로 주소 공간의 하부에 위치한다.

반면에 멀티 쓰레드 프로세스의 경우에는 각 쓰레드가 독립적으로 실행되며 쓰레드가 실행하기 위해 여러 루틴들을 호출할 수 있다.

주소 공간에는 하나의 스택이 아니라 쓰레드마다 스택이 할당되어 있다.

이를 쓰레드-로컬 저장소(thread-local storage)라 부른다.


2. 왜 쓰레드를 사용하는가?

  1. 병렬 처리

  2. 느린 I/O로 인해 프로그램 실행이 멈추지 않도록 하기 위함


3. 예제: 쓰레드 생성

다음에 실행될 스레드는 OS 스케줄러(scheduler)에 의해 결정되며, 스케줄러가 현명한 알고리즘을 구현할 법 하지만 특정 순간에 어떤 쓰레드가 실행될 지 알아내는 것은 어렵다.


4. 문제의 핵심: 제어 없는 스케줄링

  • 경쟁 조건(race condition): 명령어의 실행 순서에 따라 결과가 달라지는 상황, 데이터 경쟁(data race)라고도 불림

  • 비결정적(indeterminate)인 결과: 컴퓨터의 작동에서 일반적으로 발생하는 결정적 결과와 달리 결과가 어떠할지 알지 못하거나 실행할 때마다 결과가 다른 경우

  • 임계 영역(critical section): 공유 변수(또는 공유 자원)를 접근하고 하나 이상의 쓰레드에서 동시에 실행되면 안 되는 코드

이와 같은 문제들을 회피하려면 쓰레드는 상호 배제(mutual exclusion)라는 기법을 사용하여서 하나의 쓰레드만이 임계 영역에 진입할 수 있도록 보장한다.

그 결과로 경쟁을 피할 수 있고 프로그램 실행 결과를 결정적으로 얻을 수 있게 된다.


5. 원자성

  • 원자성(atmoicity): 하나의 단위, 전부 아니면 전무

우리가 해야할 일은 하드웨어에 동기화 함수(synchronization primitives) 구현에 필요한 몇 가지 유용한 명령어를 요청하는 것이다.

profile
Backend Engineer

0개의 댓글