스레드와 Allocator, 그리고 왜 같이 이야기해야 하는가

이미지 처리, 추론 파이프라인, 고성능 시스템을 다루다 보면
자연스럽게 “스레드”와 “allocator”라는 단어를 만나게 된다.
이 둘은 각각 따로 보면 단순하지만, 같이 쓰이기 시작하는 순간 매우 중요한 설계 포인트가 된다.

이 글에서는

  • 스레드란 무엇인지
  • allocator란 무엇인지
  • 왜 이 둘의 관계를 반드시 이해해야 하는지
    를 기초부터 정리한다.

스레드(Thread)란 무엇인가

정의

스레드는 프로그램 안에서 실제로 코드를 실행하는 실행 흐름 단위다.

  • 하나의 프로세스 안에 여러 스레드가 존재할 수 있다
  • 각 스레드는 독립적인 실행 순서를 가진다
  • 여러 스레드는 동시에 실행될 수 있다

중요한 점은

서로 다른 스레드가 같은 코드, 같은 데이터에 동시에 접근할 수 있다
는 사실이다.


스레드 자체가 문제가 아니라, “공유”가 문제다

스레드가 위험한 이유는 스레드 그 자체가 아니라
여러 스레드가 하나의 자원을 공유할 때 발생한다.

예를 들면:

  • 같은 이미지 버퍼
  • 같은 결과 구조체
  • 같은 메모리 관리자

이런 공유 자원에 대해
두 스레드가 동시에 읽고 쓰기를 하면 경쟁 상태(race condition) 가 발생한다.

이 버그는

  • 재현이 어렵고
  • 환경에 따라 나타났다 사라지고
  • 디버깅이 매우 까다롭다

그래서 멀티스레드 환경에서는
“무엇을 공유하는가”가 가장 중요해진다.


Allocator란 무엇인가

정의

allocator는 메모리를 어떻게 할당하고, 어떻게 회수할지를 관리하는 객체다.

주요 역할은 다음과 같다.

  • 메모리 할당
  • 메모리 해제
  • 재사용(pooling)을 통한 성능 최적화

일반적인 new, malloc 대신
전용 allocator를 쓰는 이유는 성능 때문이다.

특히

  • 같은 크기의 메모리를 자주 쓰거나
  • 짧은 생명주기의 임시 버퍼가 많을 때
    allocator는 큰 차이를 만든다.

allocator는 “상태를 가진 객체”다

여기서 중요한 포인트가 나온다.

allocator는 내부적으로 다음과 같은 상태(state) 를 가진다.

  • 다음에 줄 메모리 위치
  • 어떤 블록이 사용 중인지 여부
  • 사용 가능한 풀의 구조

즉,

allocator는 단순한 함수가 아니라
내부 상태를 계속 수정하는 객체다.


스레드와 allocator가 만나면 생기는 문제

여러 스레드가 하나의 allocator에 동시에 접근하면 어떤 일이 생길까?

예를 들어:

  • 스레드 A가 메모리를 할당하려는 순간
  • 스레드 B도 동시에 할당을 시도한다면

allocator 내부 상태가 동시에 수정되면서

  • 같은 메모리를 두 번 주거나
  • 내부 구조가 깨질 수 있다

이 문제를 막기 위해 선택지는 두 가지다.


PoolAllocator와 UnlockedPoolAllocator의 차이

PoolAllocator

  • 내부 상태를 락(mutex)으로 보호
  • 여러 스레드가 동시에 접근해도 안전
  • 대신 락으로 인한 성능 비용이 존재

UnlockedPoolAllocator

  • 내부 상태 보호 없음
  • 단일 스레드에서만 사용 가능
  • 락이 없어서 더 빠름

즉, 차이는 단순하다.

  • 안전함 vs 성능
  • 멀티스레드 가능 vs 단일 스레드 전용

“단일 스레드가 보장된다”는 말의 진짜 의미

이 말은 단순히

  • 지금은 하나의 스레드에서만 쓰인다
    라는 뜻이 아니다.

의미는 다음과 같다.

allocate와 free가
항상 동일한 하나의 스레드에서만 호출됨이 설계와 구조 차원에서 확정된 상태

아래 중 하나라도 가능하다면
단일 스레드 보장이 아니다.

  • 다른 스레드에서 free가 호출될 수 있음
  • 비동기 콜백이 다른 스레드에서 실행됨
  • 스레드풀에서 작업이 실행됨

이 경우 UnlockedPoolAllocator를 공유해서 쓰는 것은 위험하다.


정리

  • 스레드는 코드를 실행하는 단위다
  • allocator는 메모리를 관리하는 상태 가진 객체다
  • 여러 스레드가 하나의 allocator를 공유하면 문제가 생길 수 있다
  • 해결 방법은 두 가지다
  • 락이 있는 allocator 사용
  • 스레드마다 allocator 분리

이 개념을 이해하면
“왜 이 상황에서 이 allocator를 써야 하는가”를
감이 아니라 설계 기준으로 판단할 수 있게 된다.

Leave a Comment