본문 바로가기
카테고리 없음

세마포어시 우선순위 역전에대해서 알아보자

by 알 수 없는 사용자 2010. 1. 25.
728x90
반응형

일단 테스트 화면을 보고 이야기 하도록 하겠습니다.

세마포어에 접근하는 태스크는 TASK1과 TASK3입니다.
TASK2는 세마포어와는 상관없이 그냥 b를 출력하게 했습니다.
태스크 우선순위는 TASK1 > TASK2 > TASK3 순으로 되어있습니다.

가장먼저 TASK1이 세마포어 구간에 접근하여 문자 'a'를 5번 출력하였습니다.
TASK1이 우선순위가 가장 높기 때문에 아무런 방해없이 작업을 끝내고 시스탬자원을 다음실행준비 태스크(TASK2)에게 넘겨줬습니다.
TASK2는 'b'를 한번 출력하고 다음 실행준비 태스크(TASK3)에게 시스탬자원을 넘겨줬습니다.

TASK3는 세마포어구간에 들어가서 'c'를 출력하는 동안에 TASK1과 TASK2의 대기 시간이 모두 돌아와 TASK1,2가 실행준비상태에
들어가게 됩니다.

스캐쥴러는 이를 확인하여 우선순위가 높은 TASK1을 실행시키지만 이미 세마포어가 TASK3에 의해 점유중이기 때문에
TASK1은 TASK3가 세마포어 구간내의 작업을 모두 끝날때까지 대기하고 시스탬자원을 다음 태스크에게 넘겨줍니다.

TASK2는 세마포어와는 상관이 없고 TASK3보다 우선순위가 높기 때문에 TASK3의 작업중간 중간에 끼어드는 모습을 볼 수 있습니다.

자 여기서 한번 생각해 보아야 할 것이 있습니다.
현재 TASK1이 우선순위가 가장 높습니다. 부득이 하게 세마포어가 TASK3에 의해 사용중이라서 TASK1은 조금의 양보를 하고 있습니다.
하지만 TASK2에 의한 시스탬자원의 선점때문에 TASK3의 작업완료 시간이 조금씩 길어지고 있습니다.
TASK1은 우선순위가 가장 높음에도 불구하고 TASK2에 의해서 작업이 조금더 지연된다고 봐야 할 것입니다.

바로 이런 현상이 우선순위 역전입니다.

이 현상을 해결하기 위해서 세마포어에 접근할때 세마포어를 사용하고 있는 태스크가 현재 접근하는 태스크보다 우선순위가 낮을 경우
현재 접근하는 태스크의 우선순위를 현재 사용중인 태스크에게 일시적으로 부여해주는 방법으로 해결하였습니다.

아래는 우선순위 역전현상을 해결한 후의 태스트 화면입니다.

열핏보면 달라진게 없는거 같지만..실제는 이렇습니다.
우선순위 역전현상에 대한 고려가 없을 때는 TASK3이 실행되는 도중 TASK2의 중간개입이 3번씩 있었습니다.
하지만 이번에는 중간개입이 2번으로 줄어든걸 볼 수 있습니다.

첫줄의  "aaaaa bcbcccc" 이것을 보고 설명을 하도록 하겠습니다.

aaaaa 는 TASK1의 작업이 모두 정상적으로 끝난것을 알 수 있습니다.
작업이 모두 끝난 후 TASK1은 2Tick을 쉬게 됩니다. 그럼 2Tick동안 하위 우선순위 태스크들이 동작하게 되겠습니다.
실행대기중인 태스들중에 우선순위가 높은 TASK2가 실행되고 'b'를 출력한후 1Tick을 쉬게 됩니다.
후에 TASK3이 실행되고 세마포어구간에 들어가 'c'를 출력하게 되고 1Tick이 지나 다시 TASK2가 깨어나게 됩니다.
TASK2는 다시 'b'를 출력하고 1Tick을 쉬게 됩니다.
이제 TASK1이 깨어났지만 세마포어가 이미 사용중에 있습니다. 그러고보니 현재 세마포어를 사용하고 있는 태스크가
자신보다 우선순위가 낮은 태스크임을 알고 자신의 우선순위를 TASK3에게 세마포어를 사용하는 동안에만 넘겨주도록합니다.
이제 다시 TASK2가 깨어났을때는 현재 실행대기중인 TASK3보다 우선순위가 낮아졌기 때문에
더이상 TASK3의 작업중간에 끼어들지 못하는 것을 알 수 있습니다.

실행 타이밍도를 그림으로 그리면 아래와 같이 되겠습니다.


이로써 우선순이 역전현상을 해결할 수 있습니다.
728x90