일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 백준 1707번
- 동적 프로그래밍(Dynamic Programming)
- 백준 2504번
- 이분 그래프(Bipartite Graph)
- 백준 1948번
- 큐(Queue)
- 알고리즘 개념
- 다익스트라 알고리즘(Dijkstra Algorithm)
- 백준 2493번
- DFS
- 백준 18352번
- 백준 2812번
- 분할 정복(Divide and Conquer)
- DFS(Depth First Search)
- 위상 정렬(Topology Sort)
- 그래프(Graph)
- 백준 17608번
- 스택(Stack)
- 위상 정렬(Topological Sort)
- 이분 탐색(Binary Search)
- 백준 2261번
- 플로이드 워셜 알고리즘(Floyd-Warshall Algorithm)
- 트리(Tree)
- 백준 9012번
- BFS(Breadth First Search)
- 그리디 알고리즘(Greedy Algorithm)
- 백준 10000번
- 백준 21606번
- BFS
- DFS & BFS
- Today
- Total
Always Be Wise
세마포어(Semaphore)란? 본문
세마포어(Semaphore)는 멀티 프로그래밍 환경에서 공유 자원에 대한 접근을 제어하기 위한 방법 중 하나로,
대표적인 프로세스(스레드) 동기화 기법이다.
이때, 공유 자원은 여러 프로세스가 공동으로 이용하는 변수, 메모리, 파일 등을 말한다.
공유 자원은 공동으로 이용되기 때문에 누가 언제 데이터를 읽거나 쓰느냐에 따라 그 결과가 달라질 수 있다.
따라서 프로세스들은 공유 자원 접근 순서를 정하여 예상치 못한 문제가 발생하지 않도록 해야 한다.
이를 조금 더 자세히 설명하자면 두 개 이상의 프로세스가 공유 자원을 병행적으로 읽거나 쓰는 상황을
경쟁 조건(Race Condition)이 발생했다고 합니다. 경쟁 조건이 발생하면 공유 자원 접근 순서에 따라 실행 결과가 달라질 수 있다.
공유 자원 접근 순서에 따라 실행 결과가 달라지는 프로그램의 영역을 임계 구역(Critical Section)이라고 한다.
임계 구역에서는 프로세스들이 동시에 작업하면 안된다.
어떤 프로세스가 임계 구역에 들어가면 다른 프로세스는 임계 구역 밖에서 기다려야 하며, 임계 구역의 프로세스가 나와야 들어갈 수 있다.
임계 구역 문제를 해결하는 방법은 다음의 세 가지 조건을 만족해야 한다.
1) 상호 배제
한 프로세스가 임계구역에 들어가면 다른 프로세스는 임계구역에 들어갈 수 없다.
2) 한정 대기
어떤 프로세스도 무한 대기하지 않아야 한다. 즉, 특정 프로세스가 임계구역에 진입하지 못하면 안된다.
3) 진행의 융통성
한 프로세스가 다른 프로세스의 진행을 방해해서는 안된다.
세마포어 적용
Semaphore(S)는 음수가 아닌 정수 값을 갖는 변수이며, 해당 변수 S는 두 개의 특별한 연산인 P, V를 통해서만 조작할 수 있다.
(이때, P와 V는 각각 try와 increment를 뜻하는 네덜란드어 Proberen과 Verhogen의 머릿글자를 딴 것이다.)
P는 임계 구역에 들어가기 전에 수행되고, V는 임계 구역에서 나올 때 수행된다.
이때, 변수 S의 값을 수정하는 연산은 모두 원자성을 만족해야한다.
다시 말해, 한 프로세스(또는 스레드)에서 S값을 변경하는 동안 다른 프로세스가 이 값을 변경해서는 안된다.
S의 값은 가능한 자원의 수로 정해지며, 그 값의 범위는 정해져있지 않다.
다만, S 값을 0 또는 1을 가지는 Semaphore를 Binary Semaphore라고 하며,
Mutex와 같이 오직 1개의 프로세스(또는 스레드)만 접근할 수 있다.
1) 생산자-소비자 문제
유한한 개수의 물건(데이터)을 임시로 보관하는 보관함(버퍼)에 여러 명의 생산자들과 소비자들이 접근한다.
생산자는 물건이 하나 만들어지면 그 공간에 저장합니다. 이 때 저장할 공간이 없는 문제가 발생할 수 있다.
소비자는 물건이 필요할 때 보관함에서 물건을 가져옵니다. 이 때 소비할 물건이 없는 문제가 발생할 수 있다.
[ 변수 ]
- Empty : 버퍼 내에 저장할 공간이 있는지를 나타낸다. (초기값은 n)
- Full : 버퍼 내에 소비할 아이템이 있는지를 나타낸다. (초기값은 0)
- Mutex : 버퍼에 대한 접근을 통제한다. (초기값은 1)
[ 프로세스 - 생산자]
do {
...
// 아이템을 생산한다.
...
wait(empty); //버퍼에 빈 공간이 생길 때까지 기다린다.
wait(mutex); //임계 구역에 진입할 수 있을 때까지 기다린다.
...
//아이템을 버퍼에 추가한다.
...
signal(mutex); //임계 구역을 빠져나왔다고 알려준다.
signal(full); //버퍼에 아이템이 있다고 알려준다.
} while (1);
[ 프로세스 - 소비자]
do {
wait(full); //버퍼에 아이템이 생길 때까지 기다린다.
wait(mutex);
...
버퍼로부터 아이템을 가져온다.
...
signal(mutex);
signal(empty); //버퍼에 빈 공간이 생겼다고 알려준다.
...
아이템을 소비한다.
...
} while (1);
2) 독자-저자 문제
독자는 공유 공간에서 데이터를 읽어옵니다. 여러 명의 독자가 동시에 데이터를 읽어오는 것이 가능합니다.
저자는 공유 공간에 데이터를 씁니다. 한 저자가 공유 공간에 데이터를 쓰고 있는 동안에는 그 저자만 접근이
가능하며, 다른 독자들과 저자들은 접근할 수 없습니다.
[ 변수 ]
- readcount : 현재 버퍼에 접근 중인 독자의 수를 나타낸다. (초기값=0)
- wrt : 저자들 사이의 관계를 통제한다. 즉, 동기화한다. (초기값=1)
- mutex : readcount와 wrt에 접근하는 것이 원자적으로 수행될 수 있도록 하는 Semaphore (초기값=1)
[ 프로세스 - 저자]
wait(wrt); // 임계구역에 들어가기 위해 허가가 나기를 기다린다.
...
// 쓰기 작업 수행
...
signal(wrt); // 임계구역에서 빠져나왔음을 알린다.
[ 프로세스 - 독자]
wait(mutex);
readcount++; // 독자 수 1 증가
if readcount = 1
wait(wrt); // 쓰고 있는 저자가 없을 때까지 기다린다.
signal(mutex);
...
// 읽기 작업 수행
...
wait(mutex);
readcount--; // 독자 수 1 감소
if readcount = 0
signal(wrt); // 독자가 없다면 이를 알린다.
signal(mutex);
'기술 관련 정리' 카테고리의 다른 글
프로세스(Process)란? (0) | 2022.03.29 |
---|---|
시스템 콜(System Call)이란? (0) | 2022.03.29 |
JPG와 PNG의 차이 (0) | 2022.03.20 |
CRDT란(feat. OT)? (0) | 2022.03.17 |
CORS(Cross Origin Resource Sharing)란? (0) | 2022.03.16 |