코딩요
쉬운코드 기술 블로그
코딩요
전체 방문자
오늘
어제
  • 분류 전체보기 (54)
    • 개발자로 성장하기 (11)
    • 컴공 (25)
      • 운영체제 (12)
      • 알고리즘 (1)
      • 데이터베이스 (11)
      • 네트워크 (1)
    • 쉬운코드 (15)
      • 쉬운코드 소개 (6)
      • 쉬운코드 영상 보는 법 (3)
      • 쉬운코드 정정 보고서 (1)
      • 쉬운코드 스토리 (4)
      • 기타 이것저것 (1)
    • 면접 tip (3)

공지사항

  • 아이폰 앱에서는 슈퍼땡스 보내지 말아주세요ㅠㅠ
  • 쉬운코드 멤버십을 소개합니다
  • 쉬운코드 운영 철학

인기 글

hELLO · Designed By 정상우.
글쓰기 / 관리자
코딩요
컴공/운영체제

CPU 도움 없이는 스레드 동기화가 어려운 이유

CPU 도움 없이는 스레드 동기화가 어려운 이유
컴공/운영체제

CPU 도움 없이는 스레드 동기화가 어려운 이유

2022. 10. 7. 10:18

 

 

* 스레드 동기화를 설명하고 있지만, 프로세스 동기화 경우에도 딱히 다르진 않습니다

 

 

 

 

대부분의 락은 CPU 도움이 필요하다

 

 

동기화(synchronization)는 여러 스레드들이 동일한 데이터를 쓰고자 할 때 데이터의 변화가 일관성 있게 진행될 수 있도록 만드는 것을 의미한다

 

동기화는 락(lock)을 통해 구현되며 대표적인 락들은 아래와 같다

 

 

spinlock          mutex        semaphore

 

 

이 세 종류의 락은 모두 CPU의 도움을 필요로 한다

 

오늘은 왜 CPU의 도움이 필요한지 설명드리겠다

 

 

 

 

👉 락이 어떻게 동기화에 사용되는지 설명하는 글 (이걸 이해해야 아래 내용을 이해할 수 있습니다)

 

 

 

 


 

 

 

스핀락 사용 예제로 설명하겠다

 

 

스핀락은 락을 쥘 때까지 반복해서 락을 쥐려고 시도하는 락이다

 

그래서 반복문에서 계속 확인을 하기 때문에 CPU를 계속 사용하게 된다는 특징이 있다

 

 

 

아래는 스핀락 방식으로 어떻게 critical section(임계 영역)을 구현되는지 나타낸다

 

volatile int lock = 0;      // global 변수

void test() {
         while (test_and_set(&lock) == 1);  // 반복 시도, CPU 계속 사용
                 // critical section 
         lock = 0;
}

 

 

 

여기서 test_and_set() 함수는

 

파라미터로 전달받은 변수의 값을 1로 바꾸고, 바뀌기 전의 기존 값을 리턴하는 함수이다

 

이 친구가 오늘의 주인공이다

 

 

 


 

 

예제 코드에서 test_and_set()을 주목하자

 

 

프로세스 A는 두 개의 스레드 x와 y가 있다고 가정해 보자

 

스레드 x와 y가 동시에 test()를 호출했고 스레드 x가 간발의 차이로 test_and_set(&lock)을 먼저 호출했다면 아래와 같은 순서로 동작하게 된다

 

 

스레드 x 스레드 y
test() 호출 test() 호출
test_and_set(&lock) 호출

=> 0을 리턴, lock은 1로 바뀜

=> while 루프 탈출
 
  test_and_set(&lock) 호출

=> 1을 리턴, lock은 1로 유지

=> while 루프 탈출 못함
critical section 영역 실행 계속해서 test_and_set(&lock) 호출 , 탈출 못함 , 무한 반복
lock = 0 ↓
test() 호출 종료 test_and_set(&lock) 호출

=> 0을 리턴, lock은 1로 바뀌어져 있음

=> while 루프 탈출
  critical section 영역 실행
  lock = 0
  test() 호출 종료

 

 

 

위 표에서 test_and_set(&lock)을 호출하는 부분을 파란색으로 표시했다

 

세 줄로 이루어진 이 동작을 하나의 셀 안에 표시한 이유는

 

이 부분이 원자적으로(atomic) 동작하기 때문이다

 

 

 

 

 

test_and_set() 원자적으로 동작해야 한다

 

test_and_set()은 원자적으로 동작해야만 하는데, 왜 그런지 test_and_set() 내부를 보면 이해할 수 있다

 

아래 test_and_set() 코드는

 

'실제로 이렇게 구현되어 있다'는 것이 아니라, 내부 동작을 코드로 설명하기 위해 작성한 것이다

 

int test_and_set(int* lockPtr) {
	int oldLock = *lockPtr;  // 기존 값 저장
	*lockPtr = 1;            // 1로 바꿈
	return oldLock;          // 기존 값 반환
}

 

 

 

만약에 test_and_set()이 원자적으로 동작하지 않는다면,

 

즉, 하나의 스레드가 test_and_set(&lock)을 호출해서 동작 중인데

 

중간에 다른 스레드가 동일한 lock 변수에 대해서 test_and_set(&lock)을 호출해서 동작하는 것이 가능하다면,

 

두 스레드에서 모두 0을 리턴하는 경우가 발생할 수 있고

 

그렇다면 critical section(임계 영역)에 두 개의 스레드가 모두 진입하게 되고,

 

결국 critical section의 중요한 속성인 mutual exclusion(상호 배제)이 깨지게 된다

 

더 이상 critical section은 critical section이 아니게 되고, 동기화는 정상적으로 동작하지 않는다

 

 

 

그렇기 때문에 test_and_set()은 반드시 원자적으로 동작해야 한다

 

한 스레드가 이미 test_and_set()을 호출 중이면, 다른 스레드는 그 호출이 끝날 때까지 기다렸다가 이어서  test_and_set()을 한다

 

즉, 다른 스레드가 중간에 개입하는 일이 없어야 한다

 

 

 

 

 

CPU와 test_and_set() 

 

여기서 CPU가 아주 큰 역할을 한다

 

CPU는 '원자적'으로 동작하는 특별한 CPU 명령어(instruction) 몇 가지를 지원하는데

 

그중에 하나가 지금까지 우리가 살펴본 test_and_set()이다

 

 

 

 

 

 


 

 

 

정리하면

 

동기화에 사용되는 락들은 'CPU'에서 제공하는 '원자적인' 명령어를 사용해서 구현된다

 

그래야만 락으로 구현된 critical section이 mutual exclusion 할 수 있다

 

 

 

 

 

 

쉬운코드는 본질에 충실합니다

 

 

 

 

 

 

👉 " 스핀락, 뮤텍스, 세마포 설명 " 영상 보러가기

 

👉  test_and_set 위키 영어 설명

 

 

저작자표시 비영리 변경금지
  • 대부분의 락은 CPU 도움이 필요하다
  • 스핀락 사용 예제로 설명하겠다
  • 예제 코드에서 test_and_set()을 주목하자
  • test_and_set() 원자적으로 동작해야 한다
  • CPU와 test_and_set() 
  • 정리하면
  • 쉬운코드는 본질에 충실합니다
'컴공/운영체제' 카테고리의 다른 글
  • 프로세스는 최소한 하나의 스레드를 가진다 (맥북에서 확인하기)
  • 프로세스와 스레드 차이 많이 헷갈려 하는 포인트
  • 운영체제에서 락(lock)을 배우는 이유
  • 스레드 컨텍스트 스위칭이 가벼운 이유
코딩요
코딩요
8년차 백엔드 개발자가 이해하기 쉽게 설명합니다. 배워서 남주는 블로그! 이해하기 쉬운 기술 블로그! 쉬운코드입니다 :)

티스토리툴바

단축키

내 블로그

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

블로그 게시글

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

모든 영역

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

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