12-1. 동기화란
동기화 목적: 협력하는 프로세스들의 실행 순서와 자원의 일관성을 보장하기 위해
동기화의 의미
협력적인 프로세스를 올바르게 실행하기 위해서 프로세스 사이의 수행 시기를 맞추는 것
- 프로세스 동기화: 프로세스 사이의 수행 시기를 맞추는 것
1. 실행 순서 제어 동기화: 올바른 순서대로 실행
2. 상호 배제 동기화: 동시 접근 불가 프로세스에 한 프로세스만 접근
1. 실행 순서 제어를 위한 동기화
읽고, 쓰는 프로세스가 있을 때
읽기 프로세스는 쓰기 프로세스 뒤에 와야 한다
2. 상호 배제를 위한 동기화
동시에 접근해서는 안 되는 자원에 동시에 접근하지 못하게 하는 것
한 프로세스가 올바르게 종료되지 않고 다른 프로세스가 접근한다면 올바르지 못한 값이 나올 수 있음
process A: 2만 원 입금, process B: 5만 원 입금, 현재 잔액: 10만 원
각 프로세스는 잔액 읽기 -> 입금 -> 저장의 과정을 거침
만약 A 프로세스가 입금 중이고 저장 과정을 거치지 않았는데
B 프로세스가 작업을 시작한다면
2만원 입금 (A프로세스 작업)이 제대로 실행되지 않음
=> 동시에 접근해서는 안된다
생산자와 소비자 문제
생산자 프로세스: 물건을 계속 생산하는 프로세스 (총합 += 1)
소비자 프로세스: 물건을 계속 소비하는 프로세스 (총합 -= 1)
총합: 공유되는 데이터
해당 과정을 코드로 작성한 뒤 여러 번 반복 실행하면 올바른 결과를 받지 못할 수 있다
=> 프로세스가 제대로 동기화 되지 않았기 때문! (동시에 접근하면 안 되는 자원에 동시에 접근했기에 발생한 문제)
(생산자의 작업이 끝나기 전에 소비하고, 소비자의 작업이 끝나기 전에 생산했기 때문)
공유 자원과 임계 구역
공유 자원: 전역 변수, 파일. io 장치, 보조기억장치 등 공유되는 자원
임계 구역: 동시에 실행하면 문제가 발생하는 코드에 접근하는 코드 영역
레이스 컨디션: 임계구역 코드를 동시 다발적으로 실행하여 문제가 발생하는 경우 (데이터 일관성 문제 발생)
두 개 이상의 프로세스가 임계 구역에 진입하려면 대기가 필요
임계 구역 문제 해결 원칙
1. 상호 배제: 한 프로세스가 임계 구역에 들어갔다면 다른 프로세스는 임계구역에 들어갈 수 없다
2. 진행: 임계 구역에 어떤 프로세스도 진입하지 않았다면 진입할 수 있다
3. 유한 대기: 임계 구역에 진입하고 싶다면 언젠가는 임계 구역에 들어갈 수 있다 (무한정 대기 X)
12-2. 동기화 기법
뮤텍스 락
탈의실의 자물쇠 기능을 구현한 것
상호 배제를 위한 동기화 도구
임계 구역에 들어가는 프로세스는 뮤테스 락으로 임계 구역에 들어갔음을 알릴 수 있고, 잠겨있다면 대기, 열려있다면 진입할 수 있다
lock = True # 자물쇠- 전역 변수
aquire() # 임계 구역 잠그기
release() # 임계 구역 잠금 해제
######
# aquire() - 임계 구역에 들어가기 전 호출
# 1. 잠겨 있다면, 열릴때까지 반복적으로 확인
# 2. 열려 있다면, 임계 구역 잠그기
def acquire():
while (look == True): # 열릴때까지 확인
...
lock = True # 잠그기
# release() - 임계 구역에서 작업 후 호출
# 1. 잠금 해제
def release():
lock = False # 잠금 해제
######
# acquire(), release()를 임계 구역 전후로 호출함으로써 하나의 프로세스만 임계 구역에 진입 가능
acquire() # 진입 전
# 임계 구역
relese() # 진입 후
임계 구역 보호 과정 (뮤텍스 락)
- 임계 구역에 진입 불가 - 락 획득 불가 (대기)
- 임계 구역 진입 가능 - 락 획득 가능 (임계 구역 잠그고 작업 진행)
- 임계 구역 빠져 나올 때 - 락 해제
- 바쁜 대기: 락이 풀릴 때까지 계속 반복하며 확인하는 것 (while (look == True):)
세마포어
공유 자원이 여러 개 있는 상황에서도 적용이 가능한 동기화 도구
stop, go 신호로 관리
뮤텍스 락 보다 일반화된 방식의 동기화 방식
(뮤텍스 락은 하나의 공유 자원에 접근하는 프로세스에 사용)
공유 자원이 여러 개 있을 경우 여러 개의 프로세스가 각각 공유 자원에 접근이 가능해야 한다 (각 공유 자원에는 하나만 접근 가능해도) - 탈의실이 3개 있는 경우 떠올리기
s = 0 # 사용 가능한 공유 자원의 개수 - 임계 구역에 진입할 수 있는 프로세스의 개수
wait() # 들어가도 되는지, 대기해야 하는지 알려주는 함수
signal() # 임계 구역 앞에서 대기하는 프로세스에게 go 신호를 주는 함수
#####
wait() # 임계 구역 진입 전 호출
# 임계 구역
signal() # 임계 구역 진입 후 호출
#####
def wait():
# 임계 구역에 진입할 수 있는 프로세스의 개수가 0 이하면, 사용 가능 자원 반복확인
while s <= 0:
continue
s -= 1 # s가 1 이상이면, s를 하나 감소시키고 임계 구역 진입
def signal():
s += 1 # 작업 종료 후 s 1 증가
2개의 자원에 3개의 프로세스 p1, p2, p3가 접근한다면
1. p1 wait() 실행, 현재 s : 2 -> s -= 1 -> 임계 구역 진입
2. p2 wait() 실행, 현재 s:1 -> s -= 1 -> 임계 구역 진입
3. p3 wait() 실행, 현재 s: 0 (진입 불가) -> 무한히 반복하며 s 확인
4. p1 작업 종료 후 signal() 호출 -> s+= 1
5. p3 s > 0 확인 -> s -= 1 -> 임계 구역 진입
...
빠른 대기 문제 해결 방법
바쁜 대기 시 cpu 주기가 낭비된다
-> wait() 함수에서 사용할 수 있는 자원이 없을 경우, 해당 프로세스 상태를 대기로 전환
-> 해당 프로세스 PCB를 세마포어 대기 큐에 넣음
-> 한 프로세스 작업이 끝나고 signal()이 호출되면
-> 대기중인 프로세스를 대기 큐에서 제거하고 프로세스 상태를 준비 큐로 바꾼 뒤 준비큐로 옮김
# 빠른 대기 문제 해결
def wait():
s -= 1 # 확인 전 감소
if (s < 0): # 사용할 수 있는 자원이 없음
add this process to Queue # PCB를 대기 큐에 삽입
sleep(); # 대기 상태
def signal():
s += 1
if (s <= 0): # 먼저 감소시키고, 증가시켜서 0이 될 수 있음 (프로세스 3개, s: 2 생각해보기)
remove a process p from Queue # 대기큐에서 프로세스 제거
wakeup(p) # 대기 -> 준비
세마포어로 프로세스 순서 제어하는 방법
s = 0 으로 두고
먼저 실행 할 프로세스 뒤에 signal 함수
다음에 실행할 프로세스 앞에 wait 함수
wait이 있기 때문에 먼저 실행될 수 없음
모니터
공유 자원과 공유 자원에 접근하기 위한 인터페이스를 묶어 관리
프로세스는 반드시 인터페이스를 통해서만 자원 접근 가능
모니터를 통해 공유 자원에 접근하려 하는 프로세스를 큐에 삽입하고, 순서대로 자원을 이용할 수 있도록 함
- 조건 변수: 프로세스, 스레드의 실행 순서를 제어하기 위해 사용
'cs > [OS] 혼자 공부하는 컴퓨터 구조 + 운영체제' 카테고리의 다른 글
[혼공컴운] chapter 13. 교착 상태 (6) | 2024.02.05 |
---|---|
[혼공 학습단 11기] 5주차 미션 (2) | 2024.02.05 |
[혼공학습단 11기] 혼공컴운 4주차 미션 (0) | 2024.01.30 |
[혼공컴운] chapter 11. CPU 스케줄링 (1) | 2024.01.30 |
[혼공컴운] chapter 10. 프로세스와 스레드 (2) | 2024.01.30 |