Mutli Task를 수행하다보면 동일한 자원에 서로다른 task가 접근하는 상황이 생길 수 있다. 이때 Race Condition 혹은 Dead Lock과 같은 문제가 발생하기도 한다.
잘알려진 자료구조인 Linked List를 통해서 Race Condition과 Dead Lock에 대해 알아보자.
Race Condition(경쟁 상태)이란 공유 자원에 대해 여러 개의 프로세스가 동시에 접근을 시도할 때 접근의 타이밍이나 순서 등이 결과값에 영향을 줄 수 있는 상태를 말한다.
wikipedia
Linked List란 하나의 노드가 값과 다음 노드의 주소를 가지고 있는 자료구조이다.
Linked List의 중간에 Node B를 추가하기 위해서는
과 같은 작업이 필요하다.
이렇게 Linked List 중간에 노드를 추가하는 작업을 2개의 Thread를 통해서 수행한다고 가정해 보자. (Thread_1는 Node B를 Thread_2는 Node C를 추가) 이때 Thread_1과 Thead_2는 동일한 메모리자원에 번갈아 가면서 동작을 수행한다.
Thread_1의 입장에서
(1) List Head의 "다음 노드주소"칸에 Node B의 주소를 입력
(2) Node B의 주소칸에 Node A의 주소값를 입력
Thread_2의 입장에서는
(a) List Head의 "다음 노드 주소"칸에 Node C의 주소를 입력
(b) Node C의 주소칸에 Node A의 주소값을 입력
이때, 동작(1)과 동작(a)는 둘다 List Head의 "다음 노드 주소칸" 이라는 자원을 사용한다. 여기서 동작(1), 동작(a)가 실행되는 순서에 따라 다른 결과가 나온다.
동작(a)가 먼저 실행되서 Head의 다음 노드 주소칸에 Node C의 주소가 들어가고,
동작(1)이 나중에 수행되면서 Head의 다음 노드 주소칸에 Node B가 들어가면 Node C를 가리키는 Node가 사라진다.
이처럼 공유 자원에 대해 여러 개의 프로세스가 동시에 접근을 시도할 때 접근의 타이밍이나 순서 등이 결과값에 영향을 줄 수 있는 상태를 Race Condition이라고 부른다.
만약 동작(1-2)와 동작(a-b)를 각각 묶어서 둘 사이에 다른 동작을 수행하지 못하도록 했다면 어떻게 됐을까?
Node B가 완전히 추가되고 Node C를 추가하면 위와 같이 모든 모드들이 정상적으로 추가될 수 있다.
이처럼 특정 작업이 수행되는 동안 다른 작업이 수행되지 못하도록 막을 경우 Race Condition을 해결할 수 있다. 이러한 작업을 Atomic Operation이라고 부른다.
다음 포스트에서 Race Condition을 방지할 수 있는 방법에 대해서 다루겠다.