-
[OS] Process SynchronizationComputer Science 2023. 4. 27. 01:18728x90
오늘로 운영체제 독학이 마무리되었다. 마무리된 김에, 이해하기 어려웠던 개념인 Process Synchronization에 대해 알아보려 한다.
프로세스 간 메시지를 전송하거나, 공유 메모리를 통해 특정 데이터를 공유하게 되는 경우 문제가 발생할 수 있다.
CPU를 할당받은 프로세스가 공유 메모리에 대한 작업을 수행하는 상황에, 중간에 다른 프로세스에서 해당 메모리 내 같은 데이터에 대한 작업이 수행되는 경우를 말한다. 이를 Race Condition이라고 한다.
Race Condition은 작업 도중 OS가 개입하는 경우 때문에 발생한다.
1. CPU의 kernel 수행 중 Interrupt 발생 시
2. 프로세스가 System Call을 요청하여 kernel 모드로 수행중인데 Context Switch 발생
3. Multiprocessor에서 shared memory 내 kernel data에 동시 접근 시
다음과 같은 경우에서 OS가 개입한다.
Race Condition이 발생했을 때, 해당 공유 데이터의 최종 연산 결과는 마지막에 그 데이터를 다룬 프로세스에 따라 달라진다.
이 문제는 Race Condition이 발생하지 않았다면 저장되어야 했을 데이터의 값이 일치하지 않아, 다음 Ready Queue에 있던 프로세스가 CPU에서 수행되었을 때 예상과 전혀 다른 값이 나오거나 오류를 발생할 수 있다.
그러면 이를 어떻게 해결해야 할까? 이 문제를 Critical Section Problem이라고도 하는데,
Pseudo Code로 해결책을 표현하면 다음과 같다.
# Critical Section Problem do{ entry section critical section exit section remainder section } while(1);
위 코드를 해석하자면, 공유 데이터에 접근한 프로세스가 있다면 해당 부분을 critical section으로 규정하여 다른 프로세스들이 접근하지 못하게끔 하고, 작업이 다 끝난 후에 프로세스는 exit 표시를 하여 나머지 프로세스들도 접근이 가능하게 한다는 것이다. 이 해결법을 구현하는 알고리즘의 완성 조건은 3가지다.
1. 상호 배제 : 한 프로세스가 critical section 부분을 수행 중이면 다른 프로세스는 그들의 critical section에 들어가면 안된다.
2. 진행 : 아무도 critical section에 있지 않은 상태에서 critical section에 들어가고자 하는 프로세스 존재 시 critical section에 들어가게 해주어야 한다.
3. 유한대기 : 프로세스가 critical section에 들어가려고 요청한 후부터 그 요청이 허용될 때까지 다른 프로세스들이 들어가는 횟수에 한계가 있어야 한다.
이제 구현한 알고리즘에 대해 차례차례 알아보자.
Algorithm 1 - Synchronization variable
int turn; initially turn = 0; "P_i can enter its critical section" if (turn == 1) do { while (turn != 0); /* My turn? */ critical section turn = 1; /* Now is your turn */ remainder section } while(1);
동기화 변수 turn을 선언하여, turn = 0 이면 자신의 차례에서 critical section에 접근하고, 작업이 끝나면 turn = 1로 바꾸어 다른 프로세스가 접근할 수 있도록 해주는 알고리즘이다. 이 코드는 앞서 본 완성조건에서 상호 배제 조건을 만족시킨다. 그러나 특정 프로세스가 다른 프로세스들에 비해 더 빈번히 critical section에 들어가야 한다면 문제가 발생한다.
위 알고리즘은 본인이 critical section에 진입하고 싶어도 다른 프로세스가 본인이 가진 값으로 바꾸어야만 critical section에 진입할 수 있는 과잉 양보의 문제가 있기 때문에, 진행 조건을 만족시키지 못한다.
Algorithm 2 - Boolean Flag
boolean flag[2]; initally flag[all] = false; /* No one is in CS */ "P_i ready to enter its critical section" if (flag[i] == true) do { flag[i] = true; while (flag[i]); critical section flag[i] = false; remainder section } while(1);
flag라는 불리언 변수를 선언하여 앞선 Algorithm 1과는 다르게 true /false 로 진입 여부를 판단하고, 또한 flag[i] = true로 critical section에 진입 의사를 표시하는 것이 특징이다. 작업을 끝마치면 flag[i] = false로 지정하여 다른 프로세스가 작업이 가능하게끔 바꾼다. 이 알고리즘은 상호 배제 조건을 만족하지만, 진행 조건을 만족시키지 못한다. 왜냐하면 flag[i] = true이나 아직 critical section에 들어가기전 timer interrupt나 system call 등의 영향으로 CPU를 빼앗기는 상황을 고려해보자. 이 경우 또한 과잉 양보의 문제를 발생시킨다.
Algorithm 3 - Peterson's Algorithm
// combined synchronization variables Algorithm 1 and 2 do { flag[i] = true; /* My intention is to enter ... */ turn = j; /* Set to his turn */ while (flag[j] && turn == j); /* wait only if ... */ critical section flag[i] = false; remainder section } while(1);
위 방법은 Algorithm 1과 2를 합친 방법이다. 먼저 critical section에 들어가겠다는 의사표현을 한 뒤에, turn을 상대방, 다음에 작업을 할 상대를 지정하고, 오직 flag[j] == true와 turn = j 일 때만 critical section에 진입할 수 있도록 하고 작업이 끝나면 다시 flag[i] = false로 지정하여 다른 프로세스가 작업이 가능하게끔 바꾼다. 이 알고리즘은 앞선 3개의 조건을 모두 만족시킨다. 그러나 CPU와 Memory를 계속 쓰면서 wait를 하는 방법이기에, 비효율적이라는 문제가 발생한다
728x90'Computer Science' 카테고리의 다른 글
[DB]SQLD_2 (0) 2023.05.25 [DB] SQLD_1 (0) 2023.05.21 [OS] vi 편집기 (0) 2023.05.09 [OS] Semaphore에 대해 (0) 2023.04.27 [OS] Synchronous I/O와 Asynchronous I/O (0) 2023.04.12