728x90
반응형
Chapter 12 프로세스 동기화
1. 동기화란
동기화/ 공유 자원/ 임계 구역/ 상호 배제
협력하여 실행되는 프로세스 -> 실행 순서와 자원의 일관성 보장 필요 => 동기화 되어야 함
동기화(Synchronization)
특정 자원에 접근할 때 한 개의 프로세스만 접근하게 하거나 프로세스를 올바른 순서대로 실행하게 하는 것
프로세스 동기화: 프로세스들 사이의 수행 시기를 맞추는 것
실행 순서 제어
동시에 실행되는 프로세스 올바른 순서대로 실행
- ex. Writer 프로세스: Book.txt 파일에 값을 저장하는 프로세스
/ Reader 프로세스: Book.txt 파일에 저장된 값을 읽어 들이는 프로세스- Writer -> Reader: 'Book.txt 안에 값이 존재' 조건 만족 -> Reader 프로세스 실행 O
상호 배제(mutual exclusion)
- 동시에 접근해서는 안 되는 자원에 하나의 프로세스만 접근하게 하기
- 공유가 불가능한 자원의 동시 사용을 피하기 위해 사용하는 알고리즘
ex. 계좌: 10만 원/ 프로세스 A: 현재 저축된 금액에 2만 원 추가/ B: 5만 원 추가
계좌의 잔액 읽어 들이기 -> 읽어 들인 잔액에 2만 원/5만 원 더하기 -> 더한 값 저장하기
IF. 동시에 실행 -> 이상한 결과 => 잔액(데이터) 동시 사용
-> 올바르게 실행 => 한 프로세스가 잔액에 접근했을 때 다른 프로세스는 기다려야 함
ex. 생산자와 소비자 문제
총합(데이터) 공유, 10으로 초기화
생산자) 버퍼에 물건 넣기 -> 물건의 총합에 해당하는 변수 1증가
소비자) 버퍼에 물건 빼기 -> 물건의 총합에 해당하는 변수 1감소
=> 생산자 100,000번/ 소비자 100,000번 동시에 실행 -> 실행 결과 총합? => 이상한 결과
생산자 프로세스와 소비자 프로세스 제대로 동기화되지 않았기 때문
소비자) 생산자의 작업 끝나기 전에 총합 수정/ 생산자) 소비자 작업 끝나기 전에 총합 수정
= 동시에 접근해서는 안 되는 자원에 동시 접근
*생산자와 소비자는 동시에 실행되는 스레드가 될 수도 있음
- 공유 자원(shared resource)
- 공동으로 이용하는 변수, 파일, 장치 등
- 임계 구역(critical section)
- 공유 자원에 접근하려는 코드 중 동시에 실행하면 문제가 발생하는 코드 영역
- 2개 이상의 프로세스가 임계 구역에 진입하고자 함 -> 둘 중 하나는 대기 필요
=> 먼저 진입한 프로세스 작업 마무리 -> 대기 프로세스 임계 구역에 진입 - 레이스 컨디션(race condition)
- 잘못된 실행 -> 여러 프로세스 동시 다발적으로 임계 구역의 코드 실행 => 문제
- 데이터의 일관성이 깨지는 문제 발생
- 컴퓨터) 저급 언어 실행(고급 언어 X) => 여러 줄의 저급 언어로 변환된 고급 언어 한 줄 실행하는 과정에서 문맥 교환
상호 배제를 위한 동기화 3가지 원칙 = 운영체제) 임계 구역 문제 해결
- 상호 배제(mutual exclusion)
- 한 프로세스가 임계 구역에 진입 O -> 다른 프로세스 임계 구역에 들어올 수 X
- 진행(progress)
- 임계 구역에 어떤 프로세스도 진입 X -> 임계 구역에 진입하고자 하는 프로세스는 들어갈 수 있어야 함
- 유한 대기(bounded waiting)
- 한 프로세스가 임계 구역에 들어가고 싶음 -> 언젠가는 임계 구역에 들어올 수 있어야 함
(임계 구역에 들어오기 위해 무한적 대기해서는 X)
- 한 프로세스가 임계 구역에 들어가고 싶음 -> 언젠가는 임계 구역에 들어올 수 있어야 함
2. 동기화 기법
뮤텍스 락/ 세마포/ 모니터
뮤텍스 락(Mutex lock: MUTual EXclusion lock)
- 동시에 접근해서는 안 되는 자원에 동시에 접근하지 않도록 만드는 도구
- 임계 구역을 잠금으로써 프로세스 간 상호 배제를 위한 동기화 도구
- acquire 함수
- 프로세스가 임계 구역에 진입하기 전에 호출하는 함수
- 임계 구역 잠겨 있음 -> 열릴 때까지(lock -> false) 임계 구역 반복적으로 확인
- 임계 구역 열려 있음 -> 임계 구역 잠금(lock -> true)
- 바쁜 대기(busy wait): 반복적으로 임계 구역 잠겨있는지 확인
- release 함수
- 임계 구역에서의 작업이 끝나고 호출하는 함수
- 현재 잠긴 임계 구역을 열어주는 함수(lock -> false)
ex. 손님: 프로세스/ 탈의실: 임계구역/ 자물쇠: 뮤텍스 락
자물쇠 역할: 프로세스들이 공유하는 전역 변수 lock
임계 구역을 잠그는 역할: acquire 함수
임계 구역의 잠금을 해제하는 역할: release 함수
프로세스(: 임계 구역 보호)
- 락을 획득 X(임계 구역에 진입 X) -> 무작적 대기
- 락을 획득 O(임계 구역에 진입 O) -> 임계 구역 잠근 뒤 임계 구역에서 작업
- 임계 구역에서 빠져나올 때 -> 임계 구역의 잠금 해제
acquire() { // 임계 구역이 잠겨 있는지 반복적 확인
while (lock == true)
;
lock = true;
}
release() {
lock = false;
}
// 하나의 프로세스만 임계 구역에서 작업
acquire(); // 자물쇠 잠겨 있는지 확인, 잠김 X -> 잠그고 들어가기
// 임계 구역 // 작업 진행
release(); // 자물쇠 반환
// 생산자 소비자 문제
acquire();
// '총합' 변수 접근
release();
C/C++, Python 등 일부 프로그래밍 언어) 사용자가 acquire, release 함수 구현하지 X -> 뮤텍스 락 기능 제공
세마포(semaphore)
~= 뮤텍스 락 But, 조금 더 일반화된 방식의 동기화 도구
- 공유 자원이 여러 개 있는 상황에서도 적용 가능한 동기화 도구
- 뮤텍스 락: 하나의 공유 자원에 접근하는 프로세스
- 이진 세마포(binary semaphore) ~= 뮤텍스 락/ 카운팅 세마포(counting semaphore)
- 전역 변수 S: 임계 구역에 진입할 수 있는 프로세스의 개수(사용 가능한 공유 자원의 개수)
- wait 함수: 임계 구역에 들어가도 좋은지, 기다려야 할지 알려줌
- signal 함수: 임계 구역 앞에서 기다리는 프로세스에 '이제 가도 좋다' 신호 줌
wait() {
while (S <= 0) // 임계 구역에 진입할 수 있는 프로세스 개수 <= 0
; // 사용할 수 있는 자원이 있는지 반복적으로 확인
S--; // 임계 구역에 진입할 수 있는 프로세스 개수 1개 이상 -> S 1감소, 임계 구역 진입
}
signal() {
S++: // S 1증가
}
// 임계 구역 전후로(= 뮤텍스 락)
wait()
// 임계 구역
signal()
프로세스 P1, P2, P3가 2개의 공유 자원에 P1, P2, P3 순서대로 접근
공유 자원 2개 -> 변수 S: 2
1. P1) wait 호출/ S: 현재 2 -> 1 감소, 임계 구역 진입
2. P2) wait 호출/ S: 현재 1 -> 1 감소, 임계 구역 진입
3. P3) wait 호출/ S: 현재 0 -> 무한히 반복하며 S 확인
4. P1) 임계 구역 작업 종료, signal() 호출/ S: 1 증가
5. P3) S가 1 됨 확인/ S: 현재 1 -> 1 감소, 임계 구역 진입
=> 사용할 수 있는 공유 자원 X -> 프로세스 무작정 무한히 반복하며 S 확인 = CPU 주기 낭비
(해결)
wait() {
S--;
if (S < 0) {
add this process to Qeueu; // 해당 프로세스 PCB -> 대기 큐에 삽입
sleep(); // 대기 상태
}
}
signal() {
S++;
if (S <= 0) {
remove a process p from Queue; // 대기 큐에 있는 프로세스 p 제거
wakeup(p); // 프로세스 p를 대기 상태 -> 준비 상태
}
}
1. P1) wait 호출/ S: 1 감소 -> S는 1 => 임계 구역 진입
2. P2) wait 호출/ S: 1 감소 -> S는 0 => 임계 구역 진입
3. P3) wait 호출/ S: 1 감소 -> S는 -1 => 본인의 PCB를 대기 큐에 넣고 대기 상태로 전환
4. P1) 임계 구역 작업 종료/ signal() 호출/ S: 1 증가 -> 0/ 대기 상태였던 P3를 대기 큐에서 꺼내 준비 큐로 옮겨줌
5. 깨어난 P3) 임계 구역 진입
6. P2) 임계 구역 작업 종료/ signal() 호출/ S: 1 증가 -> 1
7. P3) 임계 구역 작업 종료/ signal() 호출/ S: 1 증가 -> 2
- 상호 배제를 위한 동기화: 동시에 접근해서는 안되는 자원에 동시에 접근하지 않도록 제어하는 것
- 실행 순서 제어를 위한 동기화: 특정 조건이 만족되어야만 실행할 수 있는 상황에서 올바르게 실행하게 하는 것
- 세마포의 변수 S를 0으로 두고 먼저 실행할 프로세스 뒤에 signal 함수, 다음에 실행할 프로세스 앞에 wait 함수
P1 실행 -> P2 실행
IF. P2 실행 -> wait 함수 => P1) 임계 구역으로 진입
-> P1) 임계 구역의 실행 끝내고 signal 호출 -> P2) 임계 구역으로 진입
모니터(monitor)
- 세마포에 비해 사용자가 사용하기 편리한 동기화 도구
- 세마포) (-) 임계 구역 앞뒤로 매번 wait, signal 함수 명시, 잘못된 코드 -> 이상한 결과
- (공유 자원 + 공유 자원에 접근하기 위한 인터페이스(통로)) -> 묶어 관리
- 프로세스는 반드시 인터페이스 통해서만 공유 자원에 접근
- 모니터 ~> 공유 자원에 접근하고자 하는 프로세스 -> 큐에 삽입, 순서대로 하나씩 공유 자원 이용
- = 공유 자원을다루는 인터페이스에 접근하기 위한 큐(모니터에 진입하기 위한 큐) 만들고,
모니터 안에 항상 하나의 프로세스만 들어오도록
=> 상호 배제를 위한 동기화 제공
- 실행 순서 제어를 위한 동기화 제공
- 특정 조건 바탕으로 프로세스 실행, 일시 중단 -> 조건 변수(condition variable) 사용
조건 변수: 프로세스나 스레드의 실행 순서를 제어하기 위해 사용하는 특별한 변수- wait: 호출한 프로세스 상태를 대기 상태로 전환, 일시적으로 조건 변수에 대한 대기 큐에 삽입하는 연산
모니터에 진입하기 위해 삽입되는 큐(상호 배제를 위한 큐): 모니터에 한 번에 하나 프로세스만 진입
!= wait 호출돼 실행이 중단된 프로세스가 삽입되는 큐(조건 변수에 대한 큐)
: 이미 모니터에 진입한 프로세스의 실행 조건이 만족될 때까지 잠시 실행이 중단돼 기다리기 위해 만들어짐 - signal: wait을 호출해 큐에 삽입된 프로세스의 실행을 재개하는 연산
- wait: 호출한 프로세스 상태를 대기 상태로 전환, 일시적으로 조건 변수에 대한 대기 큐에 삽입하는 연산
- 특정 조건 바탕으로 프로세스 실행, 일시 중단 -> 조건 변수(condition variable) 사용
모니터에 진입한 어떤 프로세스가 x.wait() ~> 조건 변수 x에 대한 wait 호출
-> 조건 변수 x에 대한 큐에 삽입 => 모니터 비게 됨(다른 프로세스 모니터 안으로 들어올 수 있음)
다른 프로세스의 signal 연산 ~> wait 연산으로 일시 중지된 프로세스 실행 재개
signal: wait 호출 -> 큐에 삽입된 프로세스의 실행 재개하는 연산
IF. 어떤 프로세스: x.signal() ~> 조건 변수 x에 대한 signal을 호출
-> 조건 변수 x에 대해 대기 상태에 있던 프로세스가 깨어나 모니터 안으로 다시 들어올 수 있음
(모니터 안에는 하나의 프로세스만 있을 수 있음)
wait 호출한 프로세스) signal을 호출한 프로세스가 모니터를 떠난 뒤에 실행
or signal을 호출한 프로세스 일시 중단 -> 자신 실행 -> signal 호출한 프로세스 수행 재개
조건 변수 -> 프로세스 실행 순서 제어를 위한 동기화 제공
- 특정 프로세스 아직 실행될 조건 X -> wait ~> 실행 중단
- 특정 프로세스 실행될 조건 충족 O -> signal ~> 실행 재개
출처
[한빛미디어] 혼자 공부하는 컴퓨터 구조+운영체제
좋은 개발자는 컴퓨터를 분석의 대상으로 바라볼 뿐, 두려워하지 않는다!‘전공서가 너무 어려워서 쉽게 배우고 싶을 때’, ‘개발자가 되고 싶은데 뭐부터 봐야 하는지 모를 때’ ‘기술 면접
hongong.hanbit.co.kr
728x90
반응형
'Computer Science > 컴퓨터구조 | 운영체제' 카테고리의 다른 글
[혼자 공부하는 컴퓨터구조+운영체제] Chapter 14 가상 메모리 (0) | 2024.07.25 |
---|---|
[혼자 공부하는 컴퓨터구조+운영체제] Chapter 13 교착 상태 (0) | 2024.07.25 |
[혼자 공부하는 컴퓨터구조+운영체제] Chapter 11 CPU 스케줄링 (1) | 2024.07.09 |
[혼자 공부하는 컴퓨터구조+운영체제] Chapter 10 프로세스와 스레드 (0) | 2024.07.09 |
[혼자 공부하는 컴퓨터구조+운영체제] Chapter 09 운영체제 시작하기 (0) | 2024.07.09 |