Common Concurrency Problem

유석현(SeokHyun Yu)·2023년 6월 14일
0

운영체제

목록 보기
16/22
post-thumbnail

1. 개요

수년 동안 병행성 관련 오류(버그) 해결을 위해 연구자들이 엄청난 시간과 노력을 들였다.

대부분의 초기 연구는 교착 상태(deadlock)에 초점이 맞추어져 있었다.


2. 오류의 종류

복잡한 병행 프로그램에서는 어떤 종류의 문제점들이 발생할까?

대부분의 오류는 교착 상태와 무관한 오류이며 나머지 오류들이 교착 상태 관련 오류이다.


3. 비 교착 상태 오류

Lu의 연구 결과를 따르면 절반 이상의 버그는 교착 상태와 무관하다.

대표적인 오류는 원자성 위반(atomicity violation) 오류와 순서 위반(order violation)이다.

원자성 위반에 대한 정의는 이렇다.

다수의 메모리 참조 연산들 간에 있어 예상했던 직렬성(serializability)이 보장되지 않았다.

즉, 코드의 일부에 원자성이 요구되었으나, 실행 시에 그 원자성이 위반되었다.

이러한 문제는 공유 변수 참조 앞뒤에 을 추가하여 어느 스레드든 proc_info 필드 접근 시, proc_info_lock 이라는 락 변수를 획득토록 한다.

순서 위반에 대한 정의는 다음과 같다.

두 개의 메모리 참조 간의 순서가 바뀌었다.

즉, A가 항상 B보다 먼저 실행되어야 하지만 실행 중에 그 순서가 지켜지지 않았다.

이러한 오류를 수정하는 방법은 순서를 강제하는 것이다.

앞에서 논의했던 것처럼 이러한 종류의 동기화에는 컨디션 변수가 잘 맞는다.


4. 교착 상태 오류

앞서 다룬 병행성 관련 오류 외에 복잡한 락 프로토콜을 사용하는 다수의 병행 시스템에서 교착 상태(deadlock)라는 고전적 문제가 발생한다.

예를 들어 락 L1을 갖고 있는 스레드 1이 또 다른 락 L2를 기다리는 상황에서 불행하게도 락 L2를 갖고 있는 스레드 2가 락 L1이 해제되기를 기다리고 있을 때 교착 상태가 발생한다.

그렇다면 교착 상태는 왜 발생하는가?

한 가지 이유는 코드가 많아지면서 구성 요소 간에 복잡한 의존성이 발생하기 때문이다.

또 다른 이유는 캡슐화(encapsulation)의 성질 때문이다.

교착 상태가 발생하기 위해서는 네 가지 조건이 충족 되어야 한다.

  • 상호 배제(Mutual Exclusion): 스레드가 자신이 필요로 하는 자원에 대한 독자적인 제어권을 주장한다

  • 점유 및 대기(Hold-and-wait): 스레드가 자신에게 할당된 자원을 점유한 채로 다른 자원을 대기한다

  • 비 선점(No preemption): 자원(락)을 점유하고 있는 스레드로부터 자원을 강제적으로 빼앗을 수 없다

  • 환형 대기(Circular wait): 각 스레드는 다음 스레드가 요청한 하나 또는 그 이상의 자원(락)을 갖고 있는 스레드들의 순환 고리가 있다


5. 회피

어떤 시나리오에서는 교착 상태를 예방하는 대신 회피하는 것이 더 유용할 때가 있다.

회피하기 위해서는 실행 중인 여러 스레드가 어떤 락을 획득하게 될 것인지에 대해 전반적으로 파악하고 있어야 하며 그것을 바탕으로 스레드들을 스케줄링 하여 교착 상태가 발생하지 않도록 그때그때 보장한다.


6. 발견 및 복구

마지막 전략은 교착 상태 발생을 허용하고, 교착 상태를 발견하면 복구토록 하는 방법이다.

profile
Backend Engineer

0개의 댓글