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

공지사항

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

인기 글

hELLO · Designed By 정상우.
글쓰기 / 관리자
코딩요

쉬운코드 기술 블로그

운영체제에서 락(lock)을 배우는 이유
컴공/운영체제

운영체제에서 락(lock)을 배우는 이유

2022. 10. 6. 09:52

 

같은 프로세스에 속하는 스레드는 메모리를 공유한다

 

 

프로세스는 서로 겹치지 않게 독립적인 메모리 주소 공간을 부여받기 때문에

 

따로 shared memery 형태로 쓰지 않는 이상 같은 메모리 공간에 접근할 일이 없어서 같은 데이터에 동시에 접근할 일이 없다

 

 

 

하지만 스레드의 경우에는 얘기가 달라진다

 

하나의 프로세스가 여러 개의 스레드들을 가질 수 있는데 이때 이 스레드들은 같은 부모 프로세스 소속이기 때문에

 

메모리 공간 또한 부모 프로세스의 메모리 공간을 공유한다

 

 

 

이렇게 하면 장점은

 

같은 부모 밑에 있는 스레드들은 따로 추가적인 조치를 해줄 필요 없이

 

스레드들 사이에서 데이터 공유가 가능해진다

 

 

 

하지만 이로 인해 필연적으로 조심해야 할 부분이 

 

여러 스레드들이 같은 데이터에 접근하다보면 예상했던 것과 다른 결과가 발생할 수 있다는 것이다

 

그리고 이 지점에서 락(lock)의 필요성이 생기게 된다

 

 

 

 

 

 

 

 

락이 없을 때 생기는 문제 

 

 

예를 들어 보겠다

 

프로세스 A는 스레드 x와 스레드 y를 가지고 있다

 

스레드 x와 y가 데이터 D에 접근을 해서 둘 다 1씩 증가시켜준다면 어떻게 될까?

 

 

 

프로그래밍 언어로는 단순하게 

 

D++;

 

로 작성하겠지만 이 명령문이 CPU 레벨에서 실행되는 명령문들로 바뀌게 되면

 

하나의 문장이 아니라 아래와 같이 복수의 명령문들이 된다 (디테일은 다를 수 있음, 지금은 이해하기 쉽게 표현)

 

 

LOAD D to R1

(메모리에서 CPU 레지스터1로 D 값을 로딩)

 

R1 = R1 + 1

(레지스터1의 값에 1을 추가해서 다시 레지스터1에 씀)

 

STORE R1 to D

(레지스터1의 값을 메모리에 있는 D의 값으로 저장)

 

 

 

그렇다면 스레드 x와 y가 동시에 D++; 를 실행하면 어떤 현상이 생길 수 있을까?

 

다양한 현상들이 생길 수 있는데 아래는 그중에 하나의 현상이다

 

(D의 초기 값은 0이며, 괄호 안에 있는 값은 명령문이 실행될 때의 값이라고 하겠다)

 

 

 

스레드 x 스레드 y
LOAD D(0) to R1  
  LOAD D(0) to R1
R1 = R1(0) + 1  
  R1 = R1(0) + 1
STORE R1(1) to D  
  STORE R1(1) to D

 

 

 

스레드 x와 y가 모두 D++; 를 했기 때문에 기대하는 최종 결과는

 

D는 2가 되는 것이지만

 

위 처럼 동작하게 되면 D의 최종 값은 1이 된다

 

 

 

 

이 문제를 해결하기 위해서 락이 등장한다

 

 

락(lock)은, 여러 스레드가 공유해서 쓰는 데이터를 보호할 때 사용된다

 

락을 쥔 스레드만 그 이후의 동작을 수행할 수 있고

 

동작 수행이 완료되면 그 스레드는 락을 반환해서 다른 스레드들이 락을 쥘 수 있도록 해야 한다

 

 

락을 쥐고 나서부터 락을 해제하기 전까지의 영역을 critical section(임계 영역)이라고 하며

 

이 영역은 일반적으로 하나의 스레드만 접근 가능하기 때문에 mutual exclusion(상호 배제)이라는 특징을 가진다

 

 

 

 

 

 

 

아까 예제의 문제를 락을 써서 해결해 보자

 

 

그럼 위의 문제를 락을 통해 해결해 보자

 

L 이라는 이름의 락을 하나 쓰기로 했다

 

아래와 같이 사용할 수 있다

 

 

 

스레드 x 스레드 y
lock(L)  
  lock(L)
LOAD D(0) to R1 |
R1 = R1(0) + 1 |
STORE R1(1) to D 락이 풀릴 때 까지 기다림
unlock(L) ↓
  LOAD D(1) to R1
  R1 = R1(1) + 1
  STORE R1(2) to D
  unlock(L)

 

 

최종 결과가 기대했던 대로 D는 2가 됨을 확인할 수 있다

 

 

 

 


 

 

정리하면,

 

 

이처럼 락(lock)은

 

여러 스레드들이 같은 데이터를 동시에 사용할 때도

 

예상대로 동작할 수 있도록 동기화(synchronization) 시켜주기 위해 사용하게 된다

 

그래서 운영체제를 배울 때 락을 배우게 되는 것이다

 

(프로세스 사이에서도 shared memory 공간을 지정해서 데이터 공유를 하게 되면 같은 문제가 발생할 수 있고 락을 통해 해결할 수 있다)

 

 

 

 

 

쉬운코드는 기본에 진심입니다

 

 

 

 

👉 " 동기화를 하지 않으면 생기는 일 " 영상 보러 가기

👉 여러 락 종류를 알려주는 영상 보러 가기

 

 

 
저작자표시 비영리 변경금지 (새창열림)
    '컴공/운영체제' 카테고리의 다른 글
    • 프로세스와 스레드 차이 많이 헷갈려 하는 포인트
    • CPU 도움 없이는 스레드 동기화가 어려운 이유
    • 스레드 컨텍스트 스위칭이 가벼운 이유
    • CPU 코어에서 컨텍스트 스위칭 되는 건 프로세스일까 스레드일까
    코딩요
    코딩요
    8년차 백엔드 개발자가 이해하기 쉽게 설명합니다. 배워서 남주는 블로그! 이해하기 쉬운 기술 블로그! 쉬운코드입니다 :)

    티스토리툴바