묻공러
[게임서버 섹션2 Note] Atomic
묻공러
묻지마공부
묻공러
전체
오늘
어제
  • 분류 전체보기 (521) N
    • C (54)
      • [코드조선] C 핵심 (35)
      • [언어본색] C 기초 (19)
    • C++ (72)
      • [루키스] C++ (9)
      • [루키스] 콜백함수 (6)
      • [루키스] STL (8)
      • [루키스] Modern C++ (11)
      • [노코프] C++ (10)
      • [노코프] Tips (16)
      • [일지] C++ (12)
    • C# (20) N
      • [루키스] C# (9)
      • [루키스] 자료구조 (3) N
      • [루키스] 실전 문법 (8) N
    • 자료구조 & 알고리즘 (50)
      • [코드조선] C 자료구조 & 알고리즘 (6)
      • [합격자되기] C++ 코딩테스트 (12)
      • [루키스] C++ 자료구조 & 알고리즘 (32)
    • CS (69)
      • [널널한 개발자] CS 개론 (19)
      • [혼자 공부하는] 컴퓨터 구조 (16)
      • [혼자 공부하는] 운영체제 (18)
      • [널널한 개발자] 네트워크 (16)
    • 게임 그래픽스 (46)
      • [전북대] OpenGL (25)
      • [일지] DirectX (21)
    • 게임 엔진 - 언리얼 (123)
      • [코드조선] 언리얼 (53)
      • [코드조선] 언리얼 데디서버 (8)
      • [일지] 언리얼 (59)
      • [일지] 언리얼 (2) (3)
    • 게임 엔진 - 유니티 (14) N
      • [최적화] 유니티 (4)
      • [루키스] 유니티 (10) N
    • 게임 서버 (17)
    • 게임 수학 & 물리 (19)
      • 게임 수학 (12)
      • 게임 물리 (7)
    • GIT & GITHUB (4)
    • 영어 (18)
      • [The Outfit] 대본 공부 (11)
      • the others (7)
    • 그 외 (14)
      • In (5)
      • Out (5)
      • Review (4)

인기 글

최근 글

hELLO · Designed By 정상우.
게임 서버

[게임서버 섹션2 Note] Atomic

2024. 12. 28. 21:38

공유 자원의 문제

#include <iostream>
#include <thread>

int32 sum = 0;

void Add()
{
	for (int32 i = 0; i < 1'000'000; i++)
	{
		sum++;
	}
}

void Sub()
{
	for (int32 i = 0; i < 1'000'000; i++)
	{
		sum--;
	}
}

int main()
{
	std::thread t1(Add);
	std::thread t2(Sub);

	t1.join();
	t2.join();

	cout << sum << endl;

}

위의 코드처럼

두 스레드에 각각 더하기와 빼기를 실행시키면

결과는 0이 아닌 이상한 값이 나온다

 

조금 더 정확하게 코드를 살펴보면

사실 sum++ 코드는 사실 한 줄로 작성된 코드이지만

실제로 어셈블리어를 확인해보면

아래의 코드처럼

사실 3단계의 과정으로 이루어져 있다

sum++;

// 실제 내부 동작
int32 eax = sum;
eax = eax + 1;
sum = eax;

 

따라서 더하기와 빼기가 한 사이클 동작하는 예시를

아래의 코드를 통해 알아보자

int32 sum = 0;

void Add()
{
	for (int32 i = 0; i < 1'000'000; i++)
	{
		//sum++;

		int32 eax = sum;// 1) eax: 0 sum: 0
		eax = eax + 1;// 3) eax: 1 sum: 0
		sum = eax;// 4) eax: 1 sum: 1
	}
}

void Sub()
{
	for (int32 i = 0; i < 1'000'000; i++)
	{
		//sum--;

		int32 eax = sum;// 2) eax: 0 sum: 0
		eax = eax - 1;// 5) eax: -1 sum: 0
		sum = eax;// 6) eax: -1 sum: -1
	}
}

위의 코드 순서처럼 한 사이클이 동작한다면

분명 Add가 한번 Sub가 한번 진행되었지만

최종적으로 sum에는 0이 아닌 -1이 저장된다

이처럼 공유자원을 여러 스레드에서 접근을 하면

문제가 발생한다

 

Atomic

위의 문제를 해결하는 한 가지 방법 중 Atomic이 있다

공유자원 변수에 Atomic을 사용하면,

해당 변수에 대해 다른 스레드가 작업을 한다면

그 작업이 끝날 때까지 기다린다

따라서 Add 중에는 Sub를 기다리고

Sub 중에는 Add를 기다리기에 서로 침범하지 않는다는 것이다

#include "pch.h"
#include <iostream>
#include "CorePch.h"
#include <thread>
#include <atomic>

atomic<int32> sum = 0;

void Add()
{
	for (int32 i = 0; i < 1'000'000; i++)
	{
		//sum++;
		sum.fetch_add(1);
	}
}

void Sub()
{
	for (int32 i = 0; i < 1'000'000; i++)
	{
		//sum--;
		sum.fetch_add(-1);
	}
}

int main()
{
	std::thread t1(Add);
	std::thread t2(Sub);

	t1.join();
	t2.join();

	cout << sum << endl;// 0 출력

}
저작자표시 비영리 변경금지 (새창열림)

'게임 서버' 카테고리의 다른 글

[게임서버 섹션2 Note] DeadLock  (0) 2024.12.29
[게임서버 섹션2 Note] Lock 기초  (0) 2024.12.28
[게임서버 섹션2 Note] 스레드 생성  (0) 2024.12.28
[게임서버 섹션2 Note] 멀티스레드 개론  (0) 2024.12.28
[게임서버 섹션1 Note] 환경 설정  (0) 2024.12.28
'게임 서버' 카테고리의 다른 글
  • [게임서버 섹션2 Note] DeadLock
  • [게임서버 섹션2 Note] Lock 기초
  • [게임서버 섹션2 Note] 스레드 생성
  • [게임서버 섹션2 Note] 멀티스레드 개론
묻공러
묻공러
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.