1 분 소요

Non Deadlock Bugs

Atomicity-Violation Bugs

어떤 메모리영역에 대해 여러개의 스레드가 접근하려고 했을 때, 공유되는 메모리영역에 대한 접근이 serialized 됐다고 생각했지만 실제로는 race condition 이 발생하는 버그 입니다.

  • MySQL bugs

Order-Violation Bugs

예를들어 A 스레드가 B 스레드보다 전에 실행된다고 기대했지만, 실제로는 Order 가 다른 경우의 bug 입니다.

Deadlock Bugs

큰 소프트웨어에선, 복잡한 상호 의존성이 발생하게 될 수 있고 그것을 미리 알아채기 쉽지 않습니다. 예를들어 가상메모리 시스템이 page fault 등의 여러 이유로 디스크의 파일 시스템에 접근해야할 경우가 있습니다. 하지만 파일시스템이 디스크의 내용을 읽어오기 위해선 가상메모리를 할당해야 하는 경우가 있습니다. 이때, Deadlock Bug 가 발생하게 됩니다. 또 다른 예로는 code들이 abstraction layer에 의해서 Encaptulation 되어있기 때문에 deadlock 을 인지하지 못하는 경우가 있습니다.

Deadlock 은 아래의 네가지 경우를 모두 만족할 때 발생합니다. 즉, 이 4가지 중 한가지라도 발생하지 않도록 하면 deadlock 을 방지할 수 있습니다.

  • Mutual exclusion
  • Hold-and-Wait
  • No preemption
  • Circular wait

Deadlock Prevention

4가지 중 한가지라도 발생하지 않도록 하여 deadlock을 예방하는 방법

circular wait

변수들에 락을 거는 순서들이 서로 다르면서 circular한 구조를 가질 때 발생합니다. 해결책으로 lock 의 순서를 define 해주게 됩니다.

Hold-and-Wait

락을 이미 가진채로 다른 락을 또 얻으려고 하는 구조를 가질때 발생합니다. 해결책으로 락을 얻을 때 락을 얻는 codeblock 을 또 한번 lock 해줌으로써 방지합니다. 하지만 모든 구조에 적용되기는 어렵습니다. critical section이 너무 커지고 미리 필요한 lock을 알아야 한다는 문제점 등이 있습니다.

No preemption

다른 스레드가 얻은 락을 다른 스레드가 강제로 뺏을 수 없습니다. 해결책으로 락을 가지고 있는 스레드가 스스로 포기하도록 구현하게 됩니다. 대표적인 방법으로 trylock() 이 있습니다. 하지만 모든 부분에서 trylock() 을 해주기는 어렵습니다.

Mutual exclusion

critical section 을 무조건 만들어야 하지만 경우에 따라서 Lock-free approach 한 경우가 있습니다. 이때, atomic instruction 을 통해 Lock-free approach 을 사용하여 deadlock 을 피할 수 있습니다.

Deadlock Avoidance

스레드들간에 deadlock이 존재할 수 있지만, system 적으로 이 deadlock 을 피해주는 방법입니다. 해당 방법은 운영체제가 응용스레드들이 어떤 락을 쓰고있고 어떤 락이 공유되는지에 대한 정보를 다 파악한 후에 그것을 기반으로 판단하게 됩니다. 하지만 이는 매우 어렵고 비현실적인 방법입니다. 그러므로 매우 소형화된 임베디드 시스템에서는 가능하지만 일반적인 서버 PC 같은 경우에는 어려운 approach 입니다.

Detect and Recover

업데이트: