[OS] Chapter 5 프로세스 동기화
summary of OS chapter 5
- 프로세스끼리 통신을 하는 경우 누가 먼저 작업할지, 작업이 언제 끝날지 등을 서로 알려주어야 하는 것을 동기화라고 한다.
- 같은 데이터를 여러 프로세스가 사용할 때는 서로 침범하면 안 되는 임계구역이 존재한다.
- 이장에서는 프로세스 동기화와 임계구역 문제를 해결하는 방법을 알아본다.
1 프로세스 간 통신
1.1 프로세스 간 통신의 개념
- 프로세스 간 통신의 종류
- 프로세스 내부 데이터 통신 - 하나의 프로세스 내에 2개 이상의 스레드가 존재하는 경우의 통신
- 프로세스 간 데이터 통신 - 같은 컴퓨터에 있는 여러 프로세스끼리 통신하는 경우로, 공용 파일 또는 운영체제가 제공하는 파이프를 사용하여 통신한다.
- 네트워크를 이용한 데이터 통신 - 여러 컴퓨터가 네트워크로 연결되어 있을 때 프로세스는 소켓을 이용하여 데이터를 주고 받는다. 다른 컴퓨터에 있는 함수를 호출하여 통신하는 원격 프로시저 호출도 여기에 해당된다.
1.2 프로세스 간 통신의 분류
1.2.1 통신 방향에 따른 분류
- 3가지 방식이 있다.
- 양방향 통신 - 데이터를 동시에 양쪽 방향으로 전송할 수 있는 구조로, 일반적인 통신은 모두 양방향 통신이다.
- 반양방향 통신 - 데이터를 양쪽 방향으로 전송할 수 있지만 동시 전송은 불가능하고 특정 시점에 한쪽 방향으로만 전송할 수 있는 구조이다.
- 단방향 통신 - 한쪽 방향으로만 데이터를 전송할 수 있는 구조이다.
- 대부분의 통신은 양방향 통신이지만, 전역 변수는 단방향 통신이다.
1.2.2 통신 구현 방식에 따른 분류
- 반복문을 무한 실행하며 기다리는 것을 바쁜 대기라고 한다. → 낭비이기 때문에 안 좋다.
- 바쁜 대기 문제를 해결하기위해 동기화를 사용한다. 운영체제가 알아서 알려준다.
- 동기화 기능이 있느냐 없느냐에 따라 대기가 있는 통신(동기화 통신)과 대기가 없는 통신(비동기화 통신)으로 구분된다.
- 대기가 있는 통신 - 동기화를 지원하고, 데이터를 받는 쪽은 데이터가 도착할 때까지 자동으로 대기 상태에 머물러 있다.
- 대기가 없는 통신 - 동기화를 지원하지 않는 통신 방식이다. 받는 쪽이 바쁜 대기를 사용한다.
1.3 프로세스 간 통신의 종류
- 프로세스 간 통신은 데이터를 주거나 받는 동작으로 이루어지며 이는 쓰기 연산과 읽기 연산으로 간소화할 수 있다.
- 프로세스 간 통신에서 가장 중요한 것은 프로세스 동기화이다.
1.3.1 전역 변수를 이용한 통신
- 공동으로 관리하는 메모리를 사용하여 데이터를 주고받는 것이다.
- 주로 직접적으로 관련이 있는 프로세스 간에 사용한다. → 부모 프로세스가 전역 변수를 선언한 후 자식 프로세스를 만들면 통신을 할 수 있다.
1.3.2 파일을 이용한 통신
- 파일 입출력 코드는 크게 세부분으로 구성되어 있다. 열고, 일거나 쓰고, 닫는다.
- 프로세스가 입출력 관리 프로세스에 쓰기를 요구하면 데이터가 저장되고, 읽기를 요구하면 입출력 관리 프로세스로부터 데이터를 가져온다.
- 부모-자식 관계 프로세스 간 통신에 많이 사용되며 운영체제가 프로세스 동기화를 제공하지 않는다. 주로 부모 함수가
wait()
함수를 써서 자식 프로세스를 기다린다.
1.3.3 파이프를 이용한 통신
- 파이프는 운영체제가 제공하는 동기화 통신 방식으로, 파일 입출력과 같이
open()
함수로 기술자를 얻고 작업을 한 후close()
함수로 마무리 한다. - 단방향 통신이고 양방향 통신을 하려면 파이프 2개를 사용해야 한다.
- 파이프의 종류
- 이름 없는 파이프 - 일반적인 파이프로, 부모와 자식 프로세스 혹은 같은 부모를 가진 자식 프로세스와 같이 서로 관련이 있는 프로세스 간 통신에 사용된다.
- 이름 있는 파이프 - FIFO라 불리는 특수 파일을 이용하며 서로 관련 없는 프로세스 간 통신에 사용한다.
1.3.4 소켓을 이용한 통신
- 여러 컴퓨터에 있는 프로세스끼리도 통신할 수 있다. 이를 네트워킹이라고 한다.
- 원격 프로시저 호출이나 소켓을 이용한다. 원격 프로시저는 다른 컴퓨터에 있는 함수를 호출하는 것이다.
- 일반적으로 원격 프로시저 호출은 소켓을 이용하여 구현한다. 소켓을 매개로 한 쪽의 프로세스와 반대쪽 프로세스를 연결하는 작업을 바인딩이라고 한다.
- 소켓을 프로세스 동기화를 지원하므로 데이터를 받는 쪽의 프로세스가 바쁜 대기를 하지 않아도 된다.
1.3.5 정리
- 프로세스 간 통신을 읽기 쓰기 연산으로 구현할 수 있다는 점이 중요하다.
- 동기화를 지원하는 프로세스는
open()
과close()
함수가 사용된다.
2 공유 자원과 임계구역
- 이 절에선느 여러 프로세스가 한정도니 자원을 가지고 공동으로 작업을 할 때 발생할 수 있는 문제를 살펴본다.
2.1 공유 자원의 접근
- 공유 자원은 여러 프로세스가 공동으로 이용하는 변수, 메모리, 파일 등을 말한다. → 프로세스들의 공유 자원 접근 순서를 정하여 예상치 못한 문제가 발생하지 않도록 해야 한다.
- 2개 이상의 프로세스가 공유 자원을 병행적으로 읽거나 쓰는 상황을 경쟁조건(race condition)이 발생했다고 한다.
2.2 임계구역
- 공유 자원 접근 순서에 따라 실행 결과가 달라지는 프로그램의 영역을 임계구역(critical section)이라고 한다.
- 임계구역에서는 프로세스들이 동시에 작업하면 안된다. → 어떤 프로세스가 임계구역에 들어가면 다른 프로세스는 임계 구역 밖에서 기다려야 하며 임계구역 프로세스가 나와야 들어갈 수 있다.
2.3 생산자-소비자 문제
- 임계구역과 관련된 전통적인 문제로 생산자-소비자 문제가 있다. → 생산자 프로세스와 소비자 프로세스가 서로 독립적으로 작업을 한다.
- 하드웨어 자원도 한 번에 한 프로세스만 사용해야 한다.
2.4 임계구역 해결 조건
- 임계 구역 문제를 해결하는 방법의 조건들
- 상호 배제 - 한 프로세스가 임계구역에 들어가면 다른 프로세스는 임계구역에 들어갈 수 없다.
- 한정 대기 - 어떤 프로세스도 무한 대기하징 않아야 한다. 즉 특정 프로세스가 이계구역에 진입하지 못하면 안 된다.
- 진행의 융통성 - 한 프로세스가 다른 프로세스의 진행을 방해해서는 안 된다는 것을 의미한다.
3 임계구역 해결 방법
- 임계구역 문제를 해결하는 단순한 방법은 잠금을 이용하는 것이다. 잠금 해제와 동시에 동기화 신호를 보내는 것이다.
- 이 절에서는 임계구역 문제를 해결하기 위한 3가지 조건인 상호배제, 한정 대기, 진행의 융통성을 모두 만족하는 잠금, 잠금 해제, 동기화 구현 방법을 알아본다.
3.1 기본 코드 소개
- 프로세스가 공유하는 변수는 공유 변수, 임계구역으로 보호되어야 할 부분은 임계구역이라고 표시할 것이다.
3.2 임계구역 해결 조건을 고려한 코드 설계
3.2.1 상호 배제 문제
1
2
3
4
while (lock == true);
lock = true;
{} // 임계구역
lock = false;
- 동시 진입 상황에는 상호 배재 조건을 충족하지 못한다.
3.2.2 한정 대기 문제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 공유 변수
boolean lock1 = false;
boolean lock2 = false;
// process 1
lock1 = true;
while (lock2 == true);
{} // 임계구역
lock1 = false;
// process 2
lock2 = true;
while (lock1 == true);
{} // 임계구역
lock2 = false;
- 두 프로세스가 모두 임계구역에 진입하지 못하는 무한 대기 현상이 일어난다.
- 프로세스가 늘어나면 검사해야하는 lock의 개수도 늘어나 비효율적이라는 확장성 문제도 있다.
3.2.3 진행의 융통성 문제
1
2
3
4
5
6
7
8
9
// process 1
while (lock == 2);
{} // 임계구역
lock = 2;
// process 2
while (lock == 1);
{} // 임계구역
lock = 1;
- 잠금을 확인하는 문장이 하나이므로 상호 배제와 한정 대기를 보장한다. 그러나 서로 번갈아가면서 실행된다는 것이 문제이다.
- 프로세스의 진행이 다른 프로세스로 인해 방해받는 현상을 경직된 동기화라고 한다. → 진행의 융통성 조건을 보장하지 못한다.
3.2.4 하드웨어적인 해결방법
1
2
3
while (testandset(&lock) == true);
{} // 임계구역
lock = false;
- 분리되어있던 두 명령어는 중간에 타임아웃이 걸리면 문제가 발생한다. 하지만 이렇게 두 명령어를 동시에 실행하면 임계구역 문제를 쉽게 해결할 수 있다.
- 바쁜 대기를 상요하여 검사하기 때문에 자원 낭비가 있다.
3.3 피터슨 알고리즘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 공유 변수
boolean lock1 = false;
boolean lock2 = false;
int turn = 1;
// process 1
lock1 = true;
turn = 2;
while(lock2 == true && turn == 2);
{} // 임계구역
lock1 = false;
// process 2
lock2 = true;
turn = 2;
while(lock1 == true && turn == 2);
{} // 임계구역
lock2 = false;
- 임계구역 해결의 세 가지 조건을 모두 만족하지만 2개의 프로세스만 사용 가능하다는 한계가 있다.
3.4 데커 알고리즘
- 이 알고리즘도 임게구역 해결의 세 가지 조건을 모두 만족하는 알고리즘이다.
- 지금까지의 알고리즘은 모두 임계구역 문제를 해결하기 위해 검사와 지정같은 하드웨어의 도움이 필요했다.
- 데커 알고리즘은 하드웨어의 도움 없이도 임계구역 문제를 해결할 수 있다는 것이 특징이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 공유 변수
boolean lock1 = false;
boolean lock2 = false;
int turn = 1;
// process 1
lock1 = true;
while (lock2 == true)
{
if (turn == 2)
{
lock1 = false;
while (turn == 2);
lock1 = true;
}
}
{} // 임계구역
turn = 2;
lock1 = false;
// process 2
lock2 = true;
while (lock1 == true)
{
if (turn == 1)
{
lock2 = false;
while (turn == 1);
lock2 = true;
}
}
{} // 임계구역
turn = 1;
lock2 = false;
- 피터슨 알고리즘이나 데커 알고리즘은 임계구역 해결의 세 가지 조건을 모두 만족하지만 매우 복잡하다. → 임계구역을 보호하기 위해 복잡한 알고리즘을 구현하도록 하는 것은 바람직한 접근 방법이 아니다.
3.5 세마포어
- 이 알고리즘은 간단하고 사용하기 쉽다.
- 세파포어는 임계구역에 진입하기 전에 스위치를 사용 중으로 놓고 임계구역으로 들어간다. → 이후에 도착하는 프로세스는 앞의 프로세스가 작업을 마칠 때까지 기다린다. → 프로세스가 작업을 마치면 세마포어는 다음 프로세스에 임계구역을 사용하라는 동기화 신호를 보낸다.
- 세마포어는 다른 알고리즘과 달리 임계구역이 잠겼는지 직접 점검하거나, 바쁜 대기를 하거나, 다른 프로세스에 동기화 메시지를 보낼 필요가 없다.
3.6 모니터
- 세마포어의 가장 큰 문제는 잘못된 사용으로 인해 임계구역이 보호받지 못한다는 것이다.
- 다음은 고의로 세마포어를 사용하지 않거나 사용 중에 실수를 해서 문제가 생긴 경우이다.
- 프로세스가 세마포어를 사용하지 않고 바로 임계구역에 들어간 경우
P()
를 두번 사용해서wake_up
신호가 발생하지 않은 경우이다.P()
와V()
를 반대로 사용하여 상호 배제가 보장되지 않은 경우
- 공유자원을 사용할 때 모든 프로세스가 세마포어 알고리즘을 따른다면 굳이
P()
와V()
를 사용할 필요 없이 자동으로 처리하면 된다. → 이를 실제로 구현한 것이 모니터이다. - 모니터는 시스템 호출과 같은 개념이다.
- 모니터의 작동 원리
- 임계구역으로 지정된 변수나 자원에 접근하고자 하는 프로세스는 직접
P()
나V()
를 사용하지 않고 모니터에 작업 요청을 한다. - 모니터는 요청받은 작업을 모니터 큐에 저장한 후 순서대로 처리하고 그 결과만 해당 프로세스에 알려준다.
- 임계구역으로 지정된 변수나 자원에 접근하고자 하는 프로세스는 직접
This post is licensed under CC BY 4.0 by the author.