설명 순서는 다음과 같습니다.
1. 자원을 공유할 때 생기는 문제
2. 동기화란
3. 임계영역
4. 임계영역 문제 해결 방법
1. 자원을 공유할 때 생기는 문제
- 두 개의 스레드가 counter라는 변수를 공유한다고 가정하고, 두 스레드 모두 counter++ 메서드를 실행할 때
- counter++ 명령문은 실제 cpu에서 실행될 때는 3개의 복합 명령문으로 되어있음(counter 변수를 로드하고, counter 값을 1증가시키고, counter에 다시 저장)
- 그래서 만약 한 스레드가 counter를 로드하고 값을 1증가시키기만 하고 Context-Switching이 발생하고 다른 스레드가 counter++을 한 경우, 업데이트되지 않은 counter값을 참조하게 됨
- 이렇게 여러 프로세스 또는 스레드가 동시에 같은 데이터를 조작할 때 타이밍이나 접근 순서에 따라서 데이터의 결과가 달라질 수 있는 상황을 'Race Condition'이라고 하고, 이것이 자원을 공유할 때 생기는 문제
2. 동기화란
- 여러 프로세스 또는 스레드를 동시에 실행해도 공유 데이터의 일관성을 유지하는 것임
- 위 문제를 보면 3개의 복합 명령문이 실행하는 도중에 Context-Switching이 발생해서 문제가 생겼으므로, '복합 명령문이 실행하는 도중에 Context-Switching이 발생하지 않게끔 하면 해결할 수 있겠다'라고 생각할 수 있음
- 하지만, 이 해결방법 Single Core일 때만 가능하고 Multi Core일 때는 불가능함. 왜냐하면, 두 스레드 모두 다른 코어에서 동시에 변수를 Load하면 아까와 같은 문제는 피할 수 없음
- 근본적인 해결방법은 공유 데이터를 한번에 한 스레드나 프로세스만 사용하도록 해야함
3. 임계영역
- 이렇게 공유 데이터의 일관성을 보장하기 위해서 한 스레드나 프로세스만 진입해서 실행 가능한 영역을 임계 영역이라고 부름
- 그리고 임계영역의 문제에 대한 해결책이 되기 위한 조건으로 아래 3가지가 있음
① 상호배제 : 한번에 하나의 프로세스 또는 스레드만 임계영역에 들어갈 수 있음
② 진행 : 만약에 임계영역이 비어있고 그 임계영역에 들어가고 싶은 프로세스나 스레드가 있을 경우, 그 중에 하나는 임계영역에 들어가서 진행이 되어야함
③ 한정된 대기 : 어떤 프로세스나 스레드가 무한정 임계영역에 들어가지 못하고 기다리고 있으면 안되는 조건
- 이 3가지 조건을 모두 만족해야 임계영역 문제에 대한 해결책이 될 수 있음
4. 임계영역 문제 해결 방법
- 임계영역의 문제를 해결하기 위한 방법은 'Lock'을 사용하는 것
- 임계영역에 들어가기 전에 락을 걸고, 한 프로세스만 임계영역을 사용한 후, 락을 풀면 이제 다음 프로세스가 임계영역에 락을 걸고 사용하는 방법임
- 락을 이용한 대표적인 임계영역 구현 방법 : Spinlock, Blocking & Wake up
① Spinlock
* 한 프로세스나 스레드가 임계영역에 들어가기 전에 lock을 걸고, 나머지는 임계영역에 들어가기 위해 lock을 획득하려고 계속 기다리는 상태
* 하지만, lock을 기다리는 동안 CPU를 낭비함. 락을 계속 확인하는 과정에 다른 프로세스나 스레드가 유용하게 사용할 수 있기 때문임
* 한정된 대기 조건을 만족시키지 못할 수 있음. 한 스레드만 계속해서 락을 가져가고, 한 스레드는 계속 락을 기다릴 수 있기 때문임
② Blocking & Wake up
* Spinlock의 단점을 극복한 것
* lock을 획득하기 위해 계속 기다리지 않고 Ready Queue에 들어가서 휴식하는 방법임
* 그러나 Mutex가 Spinlock 항상 좋은 것은 아님. 멀티코어 환경에서 임계영역에서의 작업이 Context-Switching보다 빠르다면 Spinlock이 더 좋은 성능을 가짐
- 락을 이용한 대표적인 임계영역 해결 방법 : Mutex, Semaphore
① Mutex
* 하나의 스레드 또는 프로세스만 임계영역에 들어갈 수 있도록 하는 방법
* 사용하려는 스레드가 lock을 걸고 임계영역을 사용한 후에 unlock을 해야, 다른 스레드가 이 임계영역을 사용할 수 있음
② Semaphore
* 정해진 수의 스레드 또는 프로세스만 임계영역에 들어갈 수 있도록 하는 방법
* 한 스레드가 임계영역에 들어가서 lock을 획득하고 unlock을 하지 않아도, 옆에 있는 스레드가 unlock을 할 경우 다른 스레드가 임계영역에 들어올 수 있음
동기화에 대해 알아볼 수 있었습니다.
'운영체제' 카테고리의 다른 글
동기, 비동기 (0) | 2023.08.31 |
---|---|
Java에서 동기화 문제 해결 (0) | 2023.08.12 |
페이지 교체 알고리즘 (0) | 2023.08.10 |
Deadlock (0) | 2023.08.08 |
Context Switching (0) | 2023.08.06 |