[학습] 데드락이란 무엇일까?

반응형
반응형

프로젝트가 끝나고 리펙토링을 진행하였다. 그리고 프로젝트 고도화를 위해 어떤것을 할 수 있을지 고민해봤다.
일단 내가 맡은 도메인으로 진행을 하는것이 좋을거 같다는 생각이 들었다.
여러가지가 있었지만 그중에서 내가 선택한것은 제고 쪽이다. 현재 동시성을 제어하기 위해 비관적락을 사용해놓은 상태다.
비관적락에 대해 복습해보자면 비관적락은 락을 앞단에서 거는거라 생각하면 좋다. 그러니까 DB에서 조회되기전에 락을 걸어서 동시성을 제어하는 방법이라고 생각하면 된다. 그렇다면 왜 비관적락인가를 생각해보면 내가 객체라고 말한적이 있었는데 잘못 말했구 DB다.
그러니까 DB는 좀 자기주장이 좀 강한 친구라고 생각하면 이해하기 쉽다. 그리고 비관적락은 외부에서 받은거라 생각하면 된다. 
즉, 자기주장이 강하니까 외부에서 처리하는걸 달갑게 생각하지는 않을거다. 그러니 비관적으로 생각한다고 이해하면 편하다. 
근데 문제가 생겼다. 지금 내가 개발한 stock부분은 하나만 생성하기 때문에 제목에서 말한 데드락이 걸릴일은 없다.
왜냐하면 하나만 계속 접근을 하는데 걸릴일이 없기 때문이다. 하지만 멀티로 만들면 어떨까?

{
  "stocks": [
    {
      "id": "1b332d6b-fa61-44fa-99b4-3f1c47bbced8",
      "productQuantity": -5
    } ,
     {
      "id": "8f889c3d-a233-4716-b94a-b854d6265ea8",
      "productQuantity": 10
    } ,
     {
      "id": "c01cccdb-78a9-4328-ba52-70b3edb2f40d",
      "productQuantity": -2
    },
     {
      "id": "f8a32b1c-c096-409e-8ae7-ee99bbecb01f",
      "productQuantity": 15
    } 
  ]
}

이거 또한 그냥 테스트를 하면 정상적으로 동작이 되어지는 것을 확인하였다.
근데 멀티스레드 환경에서도 정상적으로 동작할 수 있다고 장담할 수 있을까?
이때 발생하는것이 데드락인데 데드락은 일반적으로 선점때문에 발생한 이슈라고 생각하면 된다.
그렇다면 데드락은 언제 발생이 되어질까?

데드락 발생 조건 (코프만의 조건, Coffman’s Conditions) https://ko.wikipedia.org/wiki/교착_상태

  1. 상호배제(Mutual exclusion 뮤텍스) : 프로세스들이 필요로 하는 자원에 대해 순차적으로 접근 하도록 보장한다. → 오로지 하나의 스레드에서만 접근할 수 있다.
  2. 점유대기(Hold and wait) : 프로세스가 할당된 자원을 가진 상태에서 다른 자원을 기다린다.
  3. 비선점(No preemption) : 프로세스가 어떤 자원의 사용을 끝낼 때까지 그 자원을 뺏을 수 없다.
  4. 순환대기(Circular wait) : 각 프로세스는 순환적으로 다음 프로세스가 요구하는 자원을 가지고 있다.

→ 이중 하나라도 만족하지 않으면 교착 상태는 발생하지 않는다. → 이들은 독립적으로 동작하지 않는다. 이중 순환대기 조건은 점유대기 조건과 비선점 조건을 만족해야 성립

그렇다면 해결 방법은 무엇일까? 
교착 상태를 관리하는 방법

  • 예방
    • 공유 자원을 사용합니다. → ex) 쓰레드 로컬을 이용
    점유 대기(Hold and Wait) 부정
    • 프로세스 대기를 없애기 위해서 프로세스가 실행되기 전에 필요한 모든 자원을 할당합니다. (자원 낭비 발생)
    • 자원을 점유하지 않고 있을 때에만 다른 자원을 요청할 수 있도록 합니다. (기아상태가 될 수 있음)
    비선점(No Preemption) 부정
    • 모든 자원에 대한 선점을 허용합니다.
    • 프로세스가 할당받을 수 없는 자원을 요청하는 경우, 기존에 가지고 있던 자원을 모두 반납하고 새 자원과 이전 자원을 얻기 위해 대기하도록 합니다. (자원 낭비 발생 )
    순환 대기(Circular Wait) 부정
    • 자원에 고유한 번호를 할당하고, 번호 순서대로 자원을 요구하도록 합니다. (자원 낭비 발생)

등 여러가지가 존재하는데 여기까지만 정리가 된거 같다.
많은 분들이 순환대기 부정을 많이 선택을 하는거 같은데 나는 의문이 든데 과연이게 최선일까?
드디에 저번에 작성한 제고에서 동시성 처리하기(2)를 작성할 수 있을거 같다.
음 쓰레드 로컬을 이용하는 방법을 선택해볼까나..

반응형

'국비지원 (스파르타)' 카테고리의 다른 글

댓글

Designed by JB FACTORY