Search
🕠

그로킹 동시성 [CH 4] - 동시성을 구현하는 재료

AI custom autofill
Published
2025/05/04
Category
Programming
Tags
BookReview

4.1 동시성 프로그래밍의 단계

개발자가 자신의 프로그램을 작고 독립적인 작업 여러 개로 구성한 다음, 이를 실행할 수 있도록 런타임 시스템에 전달하는 과정
런타임 시스템은 시스템 자원을 가장 효율적으로 사용할 수 있게 작업의 실행을 지휘하며 적합한 처리 자원에 각 작업을 배정
→ 가장 많이 쓰이는 추상
프로세스(process)
스레드(thread)

4.2 프로세스

실행중인 프로그램을 나타내기 위해 운영체제가 제공하는 추상을 프로세스라고 한다. 이보다 아래인 기계어 수준에서는 프로세스의 개념이 없음
운영체제에서 프로세스를 사용하는 이유는 작업과 하드웨어 자원을 이들의 실제 실행과 분리하기 위함
하드웨어 자원을 함께 공유하며 운영체제의 관리를 받음
운영체제 속에서 처리 자원을 할당받은 주체의 단위
가장 큰 장점은 프로그램의 실행이 독립적이며 시스템의 나머지 부분과 완전히 격리된다는 점
프로세스 간의 통신은 어려워졌고, 우회하면 직접 접근하는 것 보다 두어 자릿수만큼 속도가 느려짐

4.2.1 프로세스의 내부 구조

다양한 정보가 포함되기 때문에 프로세스를 새로 만드는 과정도 복잡하다

4.2.2 프로세스의 상태

1.
생성: 운영체제가 프로세스를 생성
2.
준비: 프로세스가 메모리에 위치하며 실행을 기다림
3.
실행: CPU가 프로세스를 실행
4.
종료: 프로세스가 종료됐거나 실패

4.2.3 다중 프로세스

자식 프로세스(Child Process)
프로세스도 시스템 콜을 통해 자신이 속한 프로세스를 만들 수 있다. = 스포닝(spwning)
자식 프로세스는 주 프로세스와 별도의 주소 공간을 갖는 독립된 복제본이다. (독립적이며 운영체제에 의해 다른 프로세스와 격리)
새로운 프로세스는 포크가 발생한 지점부터 실행된다. 그리고 프로세스의 내부 상태도 함께 복제된다.
프리포크(prefork)
프리포크란 서버가 시작될 때 미리 포크해두고, 이들 자식 프로세스가 이후 들어오는 요청을 처리하는 구조
Niginx, 아파치 HTTP, 구니콘(Gunicorn) 등이 이렇게 동작하는 모드를 이용해 수백 개의 요청을 동시에 처리한다.

4.3 스레드

대부분의 운영체제에서는 프로세스끼리 메모리를 공유하게 할 수 있다. 그러기 위해서는, 스레드(thread)라는 또 다른 추상화 수단을 쓰면 프로세스끼리 좀 더 많은 부분을 공유할 수 있다.
스레드란 운영체제가 실행을 제어하는 인스트럭션의 독립적인 스트림을 말한다.
프로그램을 구성 요소별로 구분했을 때 프로세스는 자원(주소 공간, 파일, 네트워크 연결 등)을 담은 용기이고, 스레드는 여기서 좀 더 동적인 부분(이 용기 안에서 실행되는 인스트럭션의 연속열)에 해당
운영체제의 관점에서, 프로세스는 자원을 할당 받는 단위이고, 스레드는 실행하는 단위가 된다.
기본 프로세스 단일 스레드
부모 프로세스와 스레드끼리 주소 공간, 파일, 네트워크 연결, 공유 데이터 등의 자원을 공유
하드웨어 제조사들은 각자 나름의 방식으로 스레드를 구현했고, 개발자들이 스레드가 적용된 애플리케이션을 이식성 있게 구현하기가 곤란했기에 표준화된 프로그래밍 인터페이스가 필요해졌다.
→ 대부분의 하드웨어 제조사는 Pthreads를 채택
모든 프로세스는 최소 하나의 스레드를 갖는다. 각 스레드는 인스트럭션을 독립적이고 안전하게 실행할 수 있도록 각기 독립적인 실행 컨텍스트를 유지한다.

4.3.1 스레드의 기능

프로세스와 피교한 스레드의 장점과 단점
장점
메모리 오버헤드(실제로 사용하려는 데이터 외에 추가로 소모되는 메모리)가 적다
프로세스는 자신만의 주소 공간, 스레드 집합, 변수 값의 복사본을 갖는 완전히 독립적인 대상이나, 스레드는 부모 스레드가 복제되지 않기 때문에(같은 프로세스에 속할 뿐) 메모리 오버헤드가 훨씬 줄어든다. ⇒ 경량 프로세스(lightweight process)
별도의 자원을 할당하거나 해제할 필요가 없으므로 생성하거나 종료하는 데 드는 계산 비용이 저렴
정보 교환 오버헤드가 적다
프로세스는 자신만의 메모리 영역을 갖지만, 스레드는 주소 공간을 공유하므로 별도의 우회 수단이나 오버헤드 없이 정보를 교환할 수 있다. 한 스레드에서 변경한 내용을 다른 스레드에서 즉시 접근할 수 있다.
SMP 시스템에서 널리 쓰인다.
단점
동기화가 필요하다
운영체제는 프로세스를 서로 완전히 격리하므로 프로세스 중 하나가 충돌을 일으켜도 다른 프로세스에는 영향을 미치지 않는다. 하지만 한 프로세스 내의 모든 스레드는 같은 자원을 공유하기 때문에 이 중 하나가 충돌하거나 데이터가 꺠지면 나머지 스레드도 영향을 받는다. (이런 일이 발생하지 않으려면 공유 자원에 대한 접근을 잘 동기화하고 스레드를 확실히 제어해야 한다.)

4.3.2 스레드 구현하기

런타임 환경이 프로그래밍 언어가 제공하는 동시성 메커니즘을 실행 시점에 물리적 스레드에 배정한다. 프로세스 생성 기능은 프로그래밍 언어에서 제공하는 고수준 추상화를 통해 제공된다. 프로세스는 소스 코드상에서 유지 및 추적하는 편이 더 쉽기 때문이다.
프로그램을 실행하면 주 실행 스레드를 생성하는 프로세스가 생성된다. 주 실행 스레드를 포함해 어떤 스레드이든 언제든지 자식 스레드를 만들 수 있다.
프로세스와 스레드는 동시성의 재료와도 같다. 스레드나 프로세스 중 무엇을 다루더라도 이들은 스레드로 간주할 수 있다. 모든 프로세스는 최소한 하나의 스레드를 갖기 때문이다.