CS공부/운영체제
[OS] 뮤텍스와 세마포어
이숭간
2021. 7. 28. 23:12
728x90
동기화를 위해서 공유자원을 관리하기 위해서 존재함
(공유자원을 안전하게 관리하기 위함 → 상호배제 달성)
임계구역 (Critical Section)
- 서로다른 두 프로세스(스레드)가 같이 접근해서는 안되는 공유 영역
- 임계구역으로 설정되어야 하는 부분이 임계구역으로 설정되지 않았을때 발생하는 문제들
- 생산자-소비자 문제
- ex)키보드문제 : 키보드에 입력하면 문자를 큐에 넣고 프로그램에서 큐에서 문자를 하나씩 얻어가는데, 이때 문자를 큐에서 빼고 head를 조정하는 부분은 임계구역으로 설정되어야 한다.
- 독자-저자
- 입출금 문제
- 생산자-소비자 문제
뮤텍스
- 공유자원을 한번에 한 프로세스(스레드)만 접근할 수 있도록 키를 기반으로 상호배제를 달성하는 방법
- 키에 해당하는 어떤 오브젝트가있고, 이를 소유한 프로세스(스레드)만 공유자원에 접근할 수 있다.
뮤텍스의 연산
- lock
- 현재의 임계구역에 들어갈 권한을 얻는다.
- 만약 누군가 들어가있다면 수행을 종료할때까지 대기한다 (entry section)
- unlock
- 내가 임계구역 사용을 끝냈다!
- 대기중인 프로세스(스레드)가 임계구역에 진입할 수 있게된다.
뮤텍스의 특징
- 일반적으로 한 프로세스 내부에서 여러 스레드의 임계구역 제어를 위해 사용된다.
- 운영체제별로 trylock기능도 제공하는데, 이는 뮤텍스를 잡았는지 여부에 따라 boolean을 리턴하여, 뮤텍스를 대기해야할때는 다른작업을 먼저 수행하면서 기다릴수도 있다.
- 카운트가 1인 특별한 세마포어가 뮤텍스다.
읽기/쓰기 뮤텍스
- 읽기만 하는 스레드는 공유자원에 동시접근 가능
- 따라서 임계구역에 무조건 하나씩만 진입시키는 뮤텍스를 사용하면 읽기만 하는 스레드를 동시에 진입시키지 못하기때문에 성능저하 발생 → 이를 보완하기위해 쓰기모드만 하나씩 진입하도록 하는 뮤텍스를 읽기/쓰기 뮤텍스라고 한다.
- 이 상황에서 쓰기스레드가 대기중인 상황이라면 이후에 임계영역에 진입하는 읽기쓰레드는 (대기중이였던)스레드가 임계영역에 진입하고 수행후 떠날때까지 대기하도록 해야한다! (쓰기스레드의 starvation방지)
세마포어
- 현재 공유자원에 접근할 수 있는 프로세스(스레드) 수를 나타내는 값을 두어 상호배제를 달성하는 방법
- 정수 변수(전역)를 사용하고, 두개의 atomic한 함수로 제어된다.
- 공유 자원에 접근할수있는 프로세스의 최대 허용치만큼 접근하여 사용할 수 있다.
- 각 프로세스는 세마포어의 값을 확인/변경할 수 있다. ( 내가 공유자원을 사용할수있는지 확인 ( 값이 1이상인지, 내가 공유자원을 쓴다 → 세마포어 값 -1)
Busy Waiting
- 아무것도 하지않는 빈 반복문을 돌다가 임계구역에 진입할수 있을때 진입하는 방법
- 빈 반복문을 반복하면서 계속 컨텍스트 스위칭이 발생 → 처리효율이 떨어진다.
- 누가 먼저 CS에 진입하게 될지 제어할수 없다는 단점이 존재
세마포어의 활용
- 싱글톤 객체 생성 메서드
- 싱글톤 패턴을 사용하는 애플리케이션에서 만약 두 스레드에서 동시에 싱글톤 생성 메서드를 호출하면 싱글톤객체라는것이 보장되지 않으므로
- 싱글톤 객체 생성 메서드에서 세마포어등을 이용해 두개 이상의 스레드가 동시접근하지 못하도록 한다.
뮤텍스와 세마포어의 차이
- 뮤텍스는 오직 1개만의 프로세스(스레드)만 접근이 가능하고, 세마포어는 세마포어의 변수만큼의 프로세스(스레드)가 접근할 수 있다.
- 상태가 0,1뿐인 binary semaphore가 뮤텍스임
- 일반적으로 뮤텍스는 한 프로세스 내부에서만 공유되지만, 세마포어는 특별한 옵션이 없다면 여러개 프로세스에서 접근이 가능하다.
- 현재 수행중인 프로세스가 아닌 다른 프로세스가 세마포어를 해제할 수 있다. 반면 뮤텍스는 락을 획득한 프로세스가 반드시 그 락을 해제해야한다.