[운영체제] 동기화
프로세스 동기화
- 하나의 자원을 한 시점에 하나의 프로세스만이 접근
스레드 동기화
- 하나의 코드 블록 또는 메소드를 한 시점에 하나의 스레드만이 접근
경쟁상황(Race Condition)
- 실행 결과가 접근이 발생한 특정 순서에 의존하는 상황
임계 영역(Critical Section)
- 멀티 스레드 환경에서 여러 개의 스레드가 동시에 접근 시 문제가 발생하는 코드 영역
1) 임계 역역 문제 해결조건
(1) 상호 배제(Mutual Exclusion)
- 한 스레드가 임계 영역에서 실행 중이면 다른 스레드는 접근 불가능
(2) 진행(Progress)
- 임계 영역에서 실행중인 스레드가 없다면, 임계 영역으로 진입하려는 스레드 중 하나는 유한한 시간 내에 진입할 수 있어야 함
(3) 한정된 대기(Bounded Waiting)
- 임계 영역에 대한 진입 요청 후 만한한 시간을 기다리지 않는 것을 보장
동기화 객체 / 동기화 기법
- 상호배제를 구현해 공유 자원에 접근 시 발생하는 문제점을 해결하는 기법
1) 크리티컬 섹션(Critical Section)
- 유저 모드의 동기화 객체
- 한 프로세스 내에서만 사용할 수 있지만 빠름
- 해당 코드에 접근하기 위해 Key가 필요하며 현재 접근한 스레드가 Key를 반환하기 전까지 다른 스레드의 진입을 막음
2) 뮤텍스(Mutex, Mutual Exclusion)
- 커널 모드 동기화 객체
- 여러 프로세스 간에 사용할 수 있지만 크리티컬 섹션보다 느림
- Locking 메커니즘(Locking/Unlocking)
- 키를 가지고 있을 때만 공유 객체에 접근 가능
- 키는 단하나이며, 소유권이 있기 때문에 키를 소유한 스레드를 제외한 다른 스레드는 임계 영역 안의 스레드 작업에 간섭할 수 없음
- 임계 영역에 하나의 스레드만 접근(Binary Semaphore)
- Busy Waiting 방지
3) 세마포어(Semaphore)
- 커널 모드 동기화 객체
- 뮤텍스와 비슷하지만 접근할 수 있는 스레드 개수를 설정 가능
- 임계 영역에 스레드가 접근할 때마다 내부 카운트 값이 감소하며, 내부 카운트 값이 0이 될 때 다른 스레드의 접근을 막음
- 동시에 자원에 접근이 허용 가능한 개수를 가진 카운터(0 : 임계 영역 진입 불가, 1이상 : 임계 영역 진입 가능)
- P 연산은 카운터 감소(스레드를 임계 영역에 전근)
- V 연산은 카운터 증가(임계 영역에서 작업 중인 스레드가 작업을 완료)
- Busy Waiting 방지
4) 모니터(Monitor)
- 세마포어 알고리즘을 자동으로 처리하도록 설계된 코드
- 은닉화 또는 캡슐화
- 보호할 자원을 임계 영역으로 숨기고, 임계 영역에서 작업할 수 있는 인터페이스만 제공해 자원을 보호
! 뮤텍스와 세마포어의 차이
(1) 동기화 대상의 개수
- 뮤텍스는 동기화 대상이 하나뿐이지만 세마포어는 동기화 대상이 하나 이상
(2) 소유권 차이
- 뮤텍스는 소유권을 갖고 있기 때문에 공유자원에 접근하고 있는 스레드만이 뮤텍스를 해제 가능
- 세마포어는 세마포어 객체를 공유하기 때문에 공유하는 자원에 접근하고 있지 않은 스레드도 해제 가능
! 세마포어와 모니터의 차이
(1) 동기화 대상의 개수
- 세마포어는 임계 영역에 한 개 이상의 스레드가 접근 가능
- 모니터는 하나의 스레드만 접근 가능
(2) 지원 언어
- JAVA에서는 모니터를 모든 객체에 기본적으로 제공
- C에서는 모니터를 제공하지 않음
(3) 편리성
- 세마포어는 내부 카운트값, P 연산, V 연산 등을 프로그래머가 매번 지정
- 모니터는 이러한 작업을 캡슐화해 신경 쓸 필요 없이 동기화 가능
! 뮤텍스와 모니터의 차이
(1) 범위
- 뮤텍스는 다른 프로세스 간에 동기화에 사용할 수 있음
- 모니터는 한 프로스세 내의 다른 스레드 간에 동기화에 사용
(2) 지원
- 뮤텍스는 커널, 프레임워크, 라이브러리에 의해 제공
- 모니터는 프레임워크나 라이브러리 자체에서 제공
- 따라서 뮤텍스는 무겁고 느리며, 모니터는 가볍고 빠름