[OS] 프로세스 동기화 : Race Condition, Mutual Exclusion Primitives

parkheeddong·2023년 4월 15일
0

Operating System

목록 보기
20/63
post-thumbnail

1. 개요

1) 멀티태스킹 시스템에는 여러 개의 프로세스가 존재한다.

2) 여러 개의 프로세스들은 시스템에는 독립적으로 실행한다. 다른 프로세스와는 관계 없이 그저 자신의 코드를 실행할 뿐이다.

3) 그러나 여러개의 프로세스들이 독립적으로 실행하다 보면, 문제들이 발생한다.

➡️ 프로세스가 (1) 공유자원(ex. cpu)에 접근하려고 할 때나, (2) 공유 데이터에 동시에 접근하려고 할 때
(여러 개의 프로세스들이 logical address space를 공유하면서 데이터에 접근하려고 할 때)

  • 공유 데이터의 대표적 예시는 '커널 데이터' 이다. 프로세스들이 시스템 콜을 하면, 커널 안에 있는 각종 데이터를 접근하게 되는데 여러 프로세스들이 모두 시스템 콜을 할 수 있기 때문에 커널의 데이터 역시 공유 데이터나 마찬가지이다.
  • 이 외에도, 두 개 이상의 프로세스가 커널 데이터가 아닌 또 다른 address space를 공유하면서, 데이터를 동시에 접근하는 경우에도 문제의 소지가 있다.

4) 어떠한 문제가 발생하는가?! => 데이터 불일치성 문제

여러 프로세스가 독립적으로 동시 접근할 경우 데이터 불일치성 문제가 발생할 수 있다.

5) 이러한 데이터의 불일치성 문제를 해결할 방법은 '프로세스 동기화' 기법이다.

6) '동기화'란, 상대방에 대한 정보를 '알고 있다'는 것을 의미한다.

동기화 대상인 프로세스 간의 정보를 주고 받는 것을 동기화라고 한다. 따라서 서로 독립적으로만 움직이지 않는다.

2. 프로세스의 특징

1) 프로세스는 전부 concurrent 하게 움직인다. (병행성)

기본적으로, 여러 프로세스들이 시스템 안에 동시에 존재한다.

2) 프로세스는 Asynchronous(비동기적)이다. (독립성)

기본적으로, 프로세스는 서로에 대한 정보를 갖고 있지 않고 독립적으로 움직인다.

참고

- Concurrency(병행성) : Multiple Processes use the processor alternatiely

여러 프로세스가 "한" 프로세서(cpu)를 번갈아 사용한다.

- Parellelism(병렬성) : Mutliple Processors in the system, Multiple processes simultaneously use them.

여러 프로세스가 "여러" 프로세서(cpu)들을 동시에 사용한다.

3. Race Condition (경쟁 조건)

여러 프로세스들이 존재하면서, 같은 데이터를 동시에 번갈아 가면서 접근하고 조작한다.
프로세스의 접근 순서에 따라서 데이터 최종 결과가 달라진다면 'race condition'이라 한다.
따라서 race condition 문제를 해결해야 한다.

✔️Example 1.

두 프로세스가 있을 때, memory에는 count 라는 변수가 있고 p1가 p2가 접근해야 한다고 생각해 보자.
p1은 count값을 1 증가시키고 p2도 count값을 1 증가시킨다.
그렇다면 결과값이 count = 2여야 정상이고, consistent한 것이다.

count += 1 의 기계어 코드는 (1) count 변수를 cpu 레지스터로 가져오고, (2) 레지스터에 1을 더하고, (3) 다시 그 값을 count에 저장하는 방식으로 진행된다.

만약 p1이 cpu에서 위 과정을 모두 진행하고 나서 p2가 그 뒤에 위 과정을 진행한다면, 문제는 발생하지 않고 data consistency는 지켜진다.

그러나 만약 p1이 위 과정을 진행하는 도중 (2)이 끝나고, 갑자기 모종의 이유(ex.인터럽트 혹은 preemption)로 인해 중지되었다고 생각해 보자. 그럼 context saving을 위해 p1의 pcb 영역에 cpu register에 있는 값들을 저장하게 된다. 그 때 Register의 값은 1이라는 것도 저장될 것이다.

그 때 p2가 실행되면, p2는 count=0을 레지스터에 가져오고, 위 연산을 실행하여 count = 1이 된다.
그리고 나서 다시 p1이 cpu를 사용하고 남은 (3)을 진행하면 count = 1이 된다.

=> 이 경우 양쪽에서 1을 더해주었는데, 1만 증가해버린 data inconsistency가 발생 = 'race condition'

✔️ Example 2.

새로운 노드 bp1을 linked list 사이에 끼워 놓기 위해서는 4가지 포인터 조정 필요하다.

근데 4가지 중 3가지 포인터 조정까지 마쳤는데 갑자기 중단되어 context saving 되고, 그 사이에 다른 프로세스 실행되면 해당 노드를 건너뛸 수 있다. => race condition

📌 Machine Instruction Cycle

기계어 명령 하나를 실행하는 과정
1) 메모리에 가서 명령을 읽어오는 Instruction Fetch
2) 명령을 해독하는 Instruction Decode
3) 필요에 따라 operand를 fetch함(메모리 등에서 가져옴)
4) Execution 해당 명령을 실행함
5) 인터럽트 체크

1~4번의 단계에서 인터럽트가 들어올 수 있지만 그 1-4를 다 마치고 나서야 인터럽트를 검사하기 때문에, 하나의 기계어 명령이 끝난 후에야 인터럽트 여부를 알 수 있다. 즉 하나의 기계어 명령은 일단 실행되면 중간에 끝나지 않는다는 점에서 기계어 명령 하나는 atomic하며, 분리 불가능하고, 중간에 인터럽트를 받지 못한다. 그러나 기계어 명령들 사이사이에는 인터럽트 받을 수 있다. 이 때 Race Condtion 등의 문제가 발생한다.

4. Critical Section Problem

1) Shared Data, Critical Data

두 개 이상의 프로세스들이 접근하고 공유하는 데이터

2) Critical Seciton

각 프로세스마다 공유 데이터에 접근하는, '각 프로세스의' 코드 영역
ex) count <- count + 1 ;

3) Mutual Exclusion

두 개 이상의 프로세스들이 같은 critical section에 들어가서 코드를 실행하지 못하도록 하는 것
예시 1에서, p1이 2번까지만 실행했는데 p2가 critical section에 들어가지 못하도록 하는 것

4) Mutual Exclusion 방법 : Mutual Exclusion Primitives

(1) enterCS() primitive

한 프로세스가 critical section에 들어오기 전에, enterCS를 수행하여 다른 프로세스가 critical section에 있는지 확인하는 것
다른 프로세스가 이미 있다면 대기한다.

(2) exitCS() primitive

critical section을 다 수행하고 나갈 때, 다른 프로세스에게 내가 빠져나갔다는 것을 알리는 것

=> enterCS와 exitCS를 통틀어 'Mutual Exclusion Primitive'라고 한다.

5) Mutual Exclusion Primitive의 조건

(1) Mutual exclusion

두 개 이상의 프로세스가 Critical section에 동시에 진입하지 못한다.

(2) Progress

Critical section에 아무것도 없는데도 프로세스에 진입하지 못하는 것은 안 된다.

(3) Bounded waiting

어떤 프로세스는 critcal section에 계속 진입할 수 있는데 어떤 프로세스만 들어가지 못하는 경우 (starvation처럼) 는 발생하면 안된다.

0개의 댓글