앞 글에서는 임계구역과 상호배제가 무엇인지 배웠다.
이 글에서는 상호배제 기반 위에서 스레드들이 문제없이 공유 자원을 활용할 수 있게 하는
멀티스레드 동기화 방법을 보겠다.
멀티스레드 동기화 방법 종류
락 방식: 뮤텍스, 스핀락
wait-signal 방식 - 세마포
뮤텍스
뮤텍스는 잠김/열림(locked/unlocked) 중 한 상태를 가지는 락 변수를 이용해서
임계구역에 진입한 한 스레드 외에 다른 스레드들을 큐에 대기시키는 기법
lock 연산/unlock 연산
lock 연산은 임계구역 들어가기 전 실행하는 entry 코드
락이 잠겨 있으면 현재 스레들을 큐에 삽입
락이 열려 있으면 락을 잠그고 임계구역 진입
unlock 연산은 임계구역 나올 때 실행하는 exit 코드
락을 열림 상태로 바꾸고 큐에 대기 중인 스레드 하나를 깨운다
lock/unlock 연산 모두 원자명령이 사용
뮤텍스는 블로킹 락, 수면 대기 락으로도 불린다.
뮤텍스 특징
단점: 임계구역이 짧을 경우 비효율적
why??
락이 잠겨 있을 때 스레드는 CPU를 내놓고 대기 큐에서 수면 상태로 들어간다. (컨텍스트 스위칭 1번)
락이 풀리면 스레드는 다시 CPU를 얻어(컨텍스트 스위칭 2번) 실행된다.
임계구역 실행 시간이 짧을 경우, 락이 잠겨 있는 시간보다 컨텍스트 스위칭하는 시간이 더 길어서 비효율적이다.
스핀락
스핀락 또한 뮤텍스와 비슷하나 대기 큐가 없다.
락이 잠겨 있을 경우 스레드가 대기 큐에 대기하는 뮤텍스와 달리
락이 열릴 때까지 락 검사를 무한 반복한다.
그래서 스핀락을 공격적인 뮤텍스라고도 부르고 바쁜 대기 락(busy-waiting lock)이라고 부른다
스핀락 특징
단점: 단일 CPU를 가진 운영체제에서 비효율적이다.
예시를 들어보면
한 스레드가 lock을 걸고 임계구역에 들어간 상태에서
스레드가 중단되어 CPU를 다른 스레드에 할당하였다
하지만 락이 잠겨있는 상태이기 때문에 두번째 CPU 타임슬라이스를 전부 소진할 때까지
계속 의미없이 락을 검사하는 코드를 실행한다.
타임슬라이스가 전부 소진되어 CPU가 첫번째 스레드를 실행하고
임계구역을 나와서 락이 풀렸을 때 비로소 두번째 스레드가 임계구역에 들어갈 수 있다.
기아 스레드가 발생할 수 있다
스핀락의 경우 스레드들이 락을 얻기 위해 무한 경쟁하기 때문에
계속 락을 얻지 못한 스레드가 발생할 수 있다.
CPU를 계속 사용함으로써 많은 비용을 소비한다.
앞에서 언급했듯이 대기 큐없이 지속적으로 락 검사 코드를 실행하기 때문에
CPU를 지속적으로 사용한다.
장점: 임계구역 코드가 짧아서 락이 빨리 열릴 때 효율적이다.
뮤텍스의 경우 락이 걸려있을 때 2번의 컨텍스트 스위칭으로 많은 시간을 소비하지만
스핀락의 경우 락이 풀렸을 때 다른 스레드가 바로 진입할 수 있어 시간적으로 효율적이다.
오늘날의 경우 멀티코어 CPU를 가진 운영체제가 대부분이고
보통 임계구역 코드는 짧게 작성됨으로 많이 사용한다.
'명품 운영체제' 카테고리의 다른 글
[명품 운영체제] 8장 복합문제 (0) | 2024.05.13 |
---|---|
[운영체제] 생산자 소비자 (2) | 2024.04.18 |
[운영체제] 세마포에 대해서 (0) | 2024.04.18 |
6. 스레드 동기화 (0) | 2024.04.18 |
[명품 운영체제] 4장 복합문제 (0) | 2024.04.03 |