42Seoul_philosoper (Mutex, Semaphore)

devicii·2022년 7월 13일
0

42

목록 보기
7/8
post-thumbnail

교착 상태 (DeadLock)

운영체제 혹은, 또는, 그리고 소프트웨어의 잘못된 자원 관리로 인하여 둘 이상의 프로세스(심하면 운영체제 자체도 포함해서)가 함께 퍼지는 현상을 말한다.
ex) 예전에 인터넷 익스플로러에 여러 탭을 틀어놓고 사용하다가 위와 같은 상황이 발생한다면 모든 탭이 사라져버리는 것과 같다 !

공유자원 (Shared Resource)

여러 프로세스, 쓰레드가 함께 이용하는 변수, 메모리, 파일 등을 의미한다.
공동으로 사용하기에 언제 어떻게 데이터를 쓰고 읽느냐에 따라 내가 예측하던 결과가 나오지 않을 수 있어서 문제가 발생할 수 있다.

경쟁 조건(Race conditon)
2개 이상의 프로세스가 공유자원을 병렬적으로 읽거나 쓰는 상황을 의미하며,
공유자원 접근 순서에 따라서 실행 결과가 달라지는 상황.

임계 영역(Critical Section)

공유자원 접근 순서에 따라 실행 결과가 달라지는 프로그램의 코드 영역을 임계 영역이라고 한다.
임계 영역 안에서 경쟁 조건이 발생한다.

교착상태가 발생하려면 네 가지의 조건을 만족해야 한다.
객체가 점유하게 함

즉 교착상태를 피하고 싶다면 위 조건 중 한 개의 특징을 이용해서 교착을 방지할 수 있다. (ex. 뮤텍스 or 세마포어)

1.상호 배제 : 한 개의 프로세스(쓰레드)가 공유자원을 사용할 때 다른 프로세스가 공유자원에 접근할 수 없도록 통제
2.점유 대기 : 할당된 공유자원을 점유한 상태로 다른 자원을 대기
3.비선점 : 공유자원이 점유가 해제되기 전에는 선점할 수 없도록 함
4.순환 대기 : 객체가 필요한 다음 자원을 다음
교착 상태가 발생할 수 있는 영역.

뮤텍스(Mutex & 세마포어(Semaphore)

뮤텍스와 세마포어는 공유자원 관리를 안전하게 하기 위하여 나온 녀석들이다. 그러나 서로 다른 방식의 상호배제를 한다는 것이 특징이다.

뮤텍스

여러 쓰레드를 사용하는 상황에서 자원에 대한 접근을 강제하기 위한 동기화 방법이다.

  1. Boolean 타입의 Lock 변수 사용.
  2. 공유자원(음식)을 사용하는 쓰레드(철학자1)가 있을 때, 다른 쓰레드(철학자2)가 공유자원에 접근한다면 Blocking 하고 대기 큐로 보낸다.
  3. Lock을 건 쓰레드에만 Lock을 해제할 수 있다.

뮤텍스는 화장실이 하나인 식당을 예로 들어본다.
식당의 화장실은 외부에 있어서 화장실을 가려면 카운터에서 키를 받아가야 한다.
즉 카운터에 키가 있으면 화장실에는 아무도 없고, 키가 없다면 화장실은 누군가 사용중이라는 뜻과도 같다.

  1. 내(철학자1)가 화장실(공유자원)을 이용하고 있는데, 다른 테이블의 아저씨(철학자2)가 맥주를 많이 마셔서 화장실을 가고 싶어졌다.

  2. 그러나 아저씨는 오줌이 마려워도 열쇠가 없기 때문에 화장실을 갈 수 없다.
    아저씨는 결국 내가 나오기 전까지는 카운터에 키를 반납하기를 기다려야 한다.(대기 큐에서 대기 중)

  3. 그 사이에 금발의 아저씨(철학자3)도 화장실이 급해져서 가고 싶지만 이미 내가 사용중이므로 먼저 기다린 맥주 아저씨가 사용하기까지 카운터에서 기다려야 한다.

  4. 내가 화장실을 다 사용하고나서, 키를 카운터에 돌려다 놓으면 기다린 순서대로 키를 받아서 화장실을 사용할 수 있다.

이것이 바로 뮤텍스다. 화장실을 이용하는 '나'는 프로세스 or 쓰레드이고, 화장실을 공유자원, 화장실 키는 공유자원에 접근하기 위한 어떤 오브젝트이다.

세마포어

  1. 세마포어 변수를 통해 wait, signal을 관리한다. 세마포어 변수는 0이상의 정수형 변수를 갖는다.
  2. 계수 세마포어로 사용할 수 있으며 접근 가능한 공유 자원의 수가 1개일 때는 이진 세마포어로 뮤텍스처럼 사용할 수 있다. (세마포어가 뮤텍스가 되는 것은 가능. 반대로는 불가능)
  3. Lock을 걸지 않은 쓰레드도 Signal을 보내 Lock 해제가 가능하다.

세마포어는 공용 화장실과도 같다. 세마포어를 이용하는 공용 화장실에는 여러 개의 칸이 있고, 공용 화장실 입구에는 현재 화장실에서 빈 변기 갯수를 보여주는 전광판이 있다. (현재 3개 변기 남음)

  1. 내가 화장실을 간다면 입구에서 남은 변기의 갯수를 확인하고, 남은 변기가 있다면, 빈 변기의 갯수를 -1 한 다음에 화장실로 입장한다. 그리고 나올 땐 빈 변기의 갯수를 +1 해준다.

  2. 모든 변기가 사용중이라면, 전광판의 빈 변기의 갯수는 0이 되고, 화장실이 급한 사람이 있다면 빈 변기의 갯수가 1이 될때까지 기다려야 한다.

  3. 이와 같이 사람들이 사용이 끝나면 빈 변기 갯수 +1, 기다리던 사람이 들어간다면 다시 -1 해주는 것을 반복한다.

이처럼 세마포어는 공통으로 관리하는 하나의 값(남은 변기 전광판)을 이요해서 상호배제를 달성한다.

세마포어도 화장실이 공유자원이며, 사람들이 쓰레드 혹은 프로세스이다. 빈 변기 갯수를 체크해주는 전광판은 현재 공유자원에 접근할 수 있는 쓰레드, 프로세스의 갯수를 나타낸다.

정리

뮤텍스와 세마포어는 모두 완벽한 기법은 아니다. 이 두 개의 기법을 사용해도 데이터 무결성을 보장할 수 없고, 데드락이 발생할 수 있다.
그러나 상호배제를 위한 기본적인 기법이다.

참고자료

Mutex, Semaphore 흐름도

Process Thread

Mutext Semaphore

profile
Life is a long journey. But code Should be short :)

0개의 댓글