[게임 서버] 1.15 원자 조작
카테고리: GameServer
태그: GameServer
이 글은 아래의 책을 자세히 정리한 후, 정리한 글을 GPT에게 요약을 요청하여 작성되었습니다.
게임 서버 프로그래밍 교과서, 배현직 저자
📦 1. 멀티스레딩
👉🏻 항목 15: 원자 조작
원자 조작(atomic operation):
뮤텍스나 임계 영역 같은 락 없이도,
여러 스레드가 안전하게 데이터를 접근/수정할 수 있도록 보장해주는 연산.
- 일반적으로 32/64비트 크기의 변수에 대해, 여러 스레드가 동시에 접근해도 하나씩만 처리된다.
🛠️ 원자 조작 기능
원자 조작은 아래와 같은 기능들을 제공한다:
- 값 더하기 (Atomic Add)
- 값 맞바꾸기 (Atomic Exchange)
- 조건부 맞바꾸기 (Atomic Compare Exchange)
👉🏻 원자성을 가진 값 더하기
volatile int a = 0;
int r = AtomicAdd(&a, 3);
a
에 3을 더하는 연산은 원자적으로 수행된다.- 연산 중에 다른 스레드가 끼어들 수 없다.
-
하지만, 반환된 r이 항상 a+3인 것은 아니다.
→ 다른 스레드가 동시에 값을 바꿨을 수도 있기 때문.
👉🏻 원자성을 가진 값 맞바꾸기
volatile int a = 3;
int r = AtomicExchange(&a, 10);
- 변수
a
의 값과10
을 원자적으로 교환한다. -
교환 전의
a
값은r
에 담긴다.→ 이 경우 연산 후
r == 3
,a == 10
👉🏻 원자성을 가진 값 조건부 맞바꾸기
volatile int a = ...;
int r = AtomicCompareExchange(&a, 10, 100);
a
가 10일 경우에만 100으로 바꾼다.a == 10
이면:- 기존
a
는r
에 저장 a
는 100으로 변경됨
- 기존
a != 10
이면:a
는 바뀌지 않음r
에는 현재a
값이 들어감
→ 즉, 조건이 맞을 때만 값을 바꾸는 조건부 갱신 연산
❓ 값을 직접 대입하지 않는 이유
단순히 a = 5
처럼 값을 넣는 연산은 원자적이지 않다.
이런 대입은 내부적으로 다음 과정을 거친다:
a
값을 읽는다- 새 값을 준비한다 (
5
) - 값을
a
에 쓴다
이 세 단계는 원자적으로 처리되지 않기 때문에, 다른 스레드가 중간에 끼어들어 값을 바꿀 수 있다.
→ 따라서 단순 대입은 데이터 경합(race condition) 을 발생시킬 수 있고,
→ 원자 조작 API에서는 이런 단순 대입 연산을 제공하지 않는다.
⚛️ 원자 조작은 어디에 쓰이나?
- OS 수준에서 제공되는 뮤텍스, 임계 영역 등의 기본 동기화 도구들은 내부적으로 원자 조작을 기반으로 만들어져 있다.
- 즉, 더 고수준의 동기화 방식은 모두 원자 조작을 바탕으로 한다.
댓글남기기