본문 바로가기
교육, 학습/CS스터디_반효경 운영체제

운영체제 - 경쟁조건(Race Condition)의 발생: 동기화의 문제점

by 개발하는 경제학도 2022. 1. 15.

강의 소개

현재 수강하고 있는 KOCW 내 이화여자대학교 운영체제(2017, 반효경) 강의의 내용을 정리하였습니다.

개발자 관점에서 운영체제 기초를 학습하는 무료 강의로 자세한 강의 내용은 수강을 추천드립니다.


 

경쟁조건(Race Condition)

 

Race condition

여러 프로세스들이 동시에 공유 데이터를 접근하는 상황에서 발생하는 문제이다.

데이터의 최종 연산 결과는 마지막에 그 데이터를 다룬 프로세스에 따라 달라진다.

이런 문제 때문에 상호 배제(Mutal Exclusion) 개념이 필요하다.

 

데이터 연산의 과정

출처: 운영체제(이화여자대학교, 2017년 1학기 반효경)

 

컴퓨터 시스템에서 데이터 연산의 순서는 이렇다.

연산할 데이터를 저장공간에서 가져온다. -> 연산한다. -> 연산 결과를 저장공간에 반영한다.

이렇게 실행과 저장 주체가 1 대 1의 관계가 아니라, 저장공간 1개를 공유하는 연산 주체가 2개 이상인 경우 문제가 발생할 수 있다.

 

여러 실행 주체가 1개의 공통 데이터를 공유할 때 race condition 발생

출처: 운영체제(이화여자대학교, 2017년 1학기 반효경)

 

연산 주체 A가 데이터를 가져가서 연산하는 도중에 데이터 반영이 되지 않은 상태를 가정하자. 

반영되기 이전에 연산 주체 B가 데이터를 가져가 연산을 수행하면 최종 결괏값은 예상하지 않았던, 잘못된 값이 나오게 된다.

이와 같이, 공유되는 데이터에 경쟁하듯이 접근하는 것을 race condition이라고 한다.

 

데이터는 프로세스 내부의 데이터일 것이다. 또한, 프로세스는 자기 자신의 주소 공간 안에 있는 데이터만 접근할 수 있다.

그렇다면 이런 race condition은 왜 발생하는 것일까?

 

 

운영 체제 때문에 race condition이 발생한다.

1) 프로세스의 시스템 콜에 의해서 커널 모드를 수행 중인데 CPU가 다른 프로세스에 넘어가는(context switch) 경우

 

프로세스 A가 시스템 콜을 호출하여 데이터를 변경하려고 하고 있었다. 하지만 변경이 채 완료되기 전에 프로세스 B 또한 시스템 콜을 하여 운영체제가 동일한 데이터를 변경한 경우 다시 프로세스 A에게 운영체제가 넘어갔을 때, 프로세스 B가 변경한 데이터를 전달하지 못할 수 있다. 이런 경우 CPU가 1개여도 이렇게 race condition가 발생되어 데이터가 잘못될 수 있다.

 

출처: 운영체제(이화여자대학교, 2017년 1학기 반효경)

 

사진에서는 프로세스 A가 시스템 콜을 통해 커널 모드에서 +1 연산을 수행하려던 중 프로세스 B의 시스템 콜 호출로 CPU를 빼앗겼다. 프로세스 B가 커널 모드에서 +1을 수행하여 작업이 완료된 뒤, 프로세스 A에게 다시 CPU가 넘어가서 연산을 수행할 때 프로세스 B의 +1 결과가 반영되지 않은 상황을 보여준다. 따라서 총 +2가 되어야 하지만, 프로세스 A의 +1 연산만 반영된 잘못된 결과를 출력한 예시이다.

 

- 해결방법

이런 경우의 해결책은 커널 모드 중에서는 CPU를 선점(preempt) 하지 않는 것이다. 즉, 커널 모드에서는 CPU를 빼앗지 않고 사용자 모드가 되었을 때 빼앗는 것이다.

 

2) 커널 모드 중 인터럽트 발생하는 경우

커널 모드가 수행 중인 상태에서 인터럽트가 발생하여 인터럽트 처리 루틴이 실행되는 상황이다. 

출처: 운영체제(이화여자대학교, 2017년 1학기 반효경)

 

커널이 증감 연산을 할 때 레지스터에서 데이터를 load 하고, 연산을 수행한 뒤, 결괏값을 메모리에 store 한다.

(아래 순서는 사진의 1,2,3과 무관하다.)

[1] 만약 데이터를 load 한 후 인터럽트가 들어온 경우, [2] 인터럽트는 하던 작업을 멈추고 인터럽트 핸들러를 통해 인터럽트를 처리하는 루틴을 수행한다. 그런데 공교롭게도 인터럽트 처리 루틴이 공유 데이터를 수정하는 작업이었다면, [3] 인터럽트가 끝난 후 원래의 커널 모드 상태로 돌아왔을 때 인터럽트에서 수행한 인터럽트 루틴은 반영이 되지 않는다. 인터럽트가 끝난 이후 커널은 load 이후부터 수행하게 되기 때문이다. 사진의 예시에서는 원하던 결과 값은 count변수에 -1 한 뒤 +1 하여 count값으로 돌아오는 것이었으나, 인터럽트 처리 루틴인 -1 반영이 되지 않고, 커널 모드에서의 +1만 수행되어 결과적으로 count+1만 된다.

 

- 해결방법

커널의 고유 변수의 값을 건드리는 동안에는 인터럽트가 발생해도 disable 하여 인터럽트가 연산이 끝나고 수행될 수 있게 한다.

 

3) 멀티 프로세서에서 공유 메모리의 커널 데이터

 

출처: 운영체제(이화여자대학교, 2017년 1학기 반효경)

CPU가 2개 이상일 때는, 커널 모드 중 인터럽트를 막는 차원이 아니다. 인터럽트를 CPU 한쪽에서 막았다고 해서 다른 쪽 CPU가 데이터를 사용하는 것을 막을 수 없기 때문이다. 

CPU가 메모리에서 데이터를 가져오기 전에 lock을 걸어 다른 CPU가 같은 데이터에 접근하는 것을 막아 준다. 연산이 끝난 후 데이터를 다시 메모리에 저장할 때 lock을 풀어 줌으로써 다른 CPU가 접근할 수 있게 해 준다.

 

- 해결방법

1) 한 번에 하나의 CPU만 운영체제를 사용하도록, 즉 1개씩만 커널에 들어갈 수 있게 하는 방법이 있다.

커널 전체에 lock을 걸기 때문에 비효율적이다.

 

2) 커널 내부에 있는 각 공유 데이터에 접근할 때마다 해당 데이터에 lock을 거는 방법이 있다.

한쪽 CPU가 공유 데이터를 사용 중일 때 lock을 건다.

 

 

프로세스 동기화 문제

공유 데이터의 동시 접근은 데이터의 불일치 문제를 유발할 수 있다.

일관성 유지를 위해서는 협력 프로세스 간의 실행 순서를 정해 주는 메커니즘이 필요하다.

race condition을 막기 위해서는 병행 (concurrent) process는 동기화되어야 한다.

 

 

임계 영역 문제 (The Critical-Section Problem)

n 개의 프로세스가 공유 데이터를 동시에 사용하기를 원할 때 각 프로세스의 code segment에는 공유 데이터를 접근하는 코드인 임계 구역 (critical section)이 존재한다.

하나의 프로세스가 임계 영역에 있을 때 lock을 걸어 다른 모든 프로세스는 임계 영역에 들어갈 수 없다.

비록 CPU를 빼앗기더라도 다른 프로세스는 임계 영역에 들어오지 못한다. 작업 완료 후 unlock 하여 다른 프로세스가 들어올 수 있게 한다.

출처: 운영체제(이화여자대학교, 2017년 1학기 반효경)

 

 

출처: 운영체제와 정보기술의 원리(반효경 저)

댓글