Cute Running Puppy

cs/[OS] 혼자 공부하는 컴퓨터 구조 + 운영체제

[혼공컴운] chapter 12. 프로세스 동기화

R.silver 2024. 2. 5. 14:06
반응형

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이 있기 때문에 먼저 실행될 수 없음 

 

모니터

 

공유 자원과 공유 자원에 접근하기 위한 인터페이스를 묶어 관리 

프로세스는 반드시 인터페이스를 통해서만 자원 접근 가능 

 

모니터를 통해 공유 자원에 접근하려 하는 프로세스를 큐에 삽입하고, 순서대로 자원을 이용할 수 있도록 함

 

- 조건 변수: 프로세스, 스레드의 실행 순서를 제어하기 위해 사용 

반응형