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 ~> 실행 재개
출처
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 |