'test and set'에 해당되는 글 1건

  1. 2012.01.07 상호배제 (Mutual Exclusion) (2)

여러가지 태스크들이 서로 정보를 주고 받을수 있는 방법 중에 가장 쉬운 방법은 무엇일까요??

바로 공유 데이터를 이용하는 것입니다. 더욱 직관적으로 표현하자면 "전역변수" 를 사용하는 것이지요 ㅋㅋ

그럼 공유자원이란 무엇인가???

말그대로 여러가지 태스크에서 공동으로 사용, 접근할수 있는 모든 것입니다~

전역변수가 될수도 있고, Public 형의 함수나 클래스가 될수도 있고, 프린터와 같은 I/O 가 될수도 있죠.

여러 테스크들이 데이터와 자원을 공유하는 것은 좋은 일이지만, 그 과정에서 테스크 사이의 경쟁이나 다른 이유에 의해서 데이터가 손실되는 상황을 막아야 합니다.

모든 테스크가 접근하여 공유자원을 사용할수 있게 하지만, 한번에 하나씩만 사용할수 있도록 하겠다! 라는 개념이 바로 상호배제 (Mutual Exclusion) 입니다.

상호 배제를 구현하는 방법은 크게 4가지가 있습니다.

(1) 인터럽스 활성화 / 비 활성화 (Interrupt Enable / Disable)
(2) Test - And - Set (TAS) 수행
(3) 스케쥴러 비활성화 (Scheduler Lock / Unlock)
(4) 세마포어의 이용 (Semaphore) (혹은 뮤텍스 (Mutex) 의 이용)

아나 많기도 엄청나게 많네 ㅋㅋ 이런 거지같은게 ㅋㅋㅋ

한번에 쓸려면 엄청난 양이겠죠? ㅋㅋㅋ

(4) 번의 세마포어는 조금 더 쓰임새가 다양한 기능이므로 뒤에서 따로 자세히 다루도록 하고, 이번에는 세마포어가 무엇인지, 어떻게 상호배제에 이용하는지 정도만 간단하게 알아보겠습니다.

흠.. 벌써부터 양이 많아질것 같이 쫄리넹. 하지만 나도 졸업고사를 보긴해야하니 한번 정리한다 생각하고 기술해볼까나 ㅋㅋ

(1) 인터럽트 활성화 / 비활성화 (Interrupt Enable / Disable)

: 왠지 익숙하시죠?? 아니라구요???  머야 ! 장난하는거야? ㅋㅋㅋ 앞에 강의에서 살짝 언급드렸는데요 ㅋ
크.리.티.컬.섹.션 할때요! ㅋㅋㅋ USART TX Function 까지 예를 들어가면서  ㅠㅠㅠㅠㅠ

이럴때 배신감 느낀다 ㅋㅋㅋ 나 중,고등학교때 선생님들이 이런 기분이였을꺼야 ㅋㅋㅋ

이 방법은 상호 배제를 실행 할 수 있는 가장 손쉬운 방법중에 하나입니다.

왜일까요??? 스케쥴러를 이해하신 분들은 이해가 가실 것입니다. 동작하고 있는 테스크에서 CPU 점유율을 테스크자신의 의지가 아닌 외부의 힘에 의해 가져오려면 필수적으로 필요한것이 ISR (Interrupt Suervice Routine) 이라고 했습니다. 그것이 틱 인터럽트이던, 외부 인터럽트이던 무조건 인터럽트로 뛰어야만이 CPU 점유율이 스케쥴러로 넘어가고, 커널의 종류가 어떤 것인가에 따라 어느 Task 로 CPU 점유율을 넘겨줄 것인지가 결정되는 것이지요.

그렇다면~

공유자원을 Access 하고 있는 동안에 인터럽트를 꺼버리고, 이용이 다 끝난 이후에 인터럽트를 다시 켠다면요???

ㅋㅋㅋ 이제 감이 오시지요?? 다른 Task 나 ISR 에 의해서 공유자원이 동시에 경쟁되는 일을 원초적으로 있을수가 없습니다.

꼭 RTOS 기반이 아니라, 전경/배경 시스템에서도 마찬가지입니다. 배경 프로세스에서 공유자원을 접근하려 할때 의도치 않은 인터럽트에 의해 데이터가 변경된다면??? 배경 시스템 입장에서는 오염된 데이터를 얻게 되는 것이지요~

간단한 Psudo Code 는 아래와 같습니다.

 인터럽트 비활성화
 리소스 액세스 (공유자원 읽기 / 쓰기);
 인터럽트 활성화


여기서 주의해야할 점이 하나 있습니다.

인터럽트의 비활성화 기간이 너무 길면 시스템의 응답성에 영향을 줄수 있으므로 주의해야 합니다.  즉, 변수의 복사나 시간이 많이 걸리는 작업이라면 이 방법을 사용하는것을 다시 한번 생각해 보셔야 합나다.

좋은 커널은 얼마의 시간동안 인터럽트 비활성화를 할 수 있는지에 대해 정보를 제공합니다. 프로그램 할때 꼭 신경쓰시기 바랍니다.

(2) Test - And -Set (TAS)

약간 생소하지요??

커널을 사용할때는 거의 사용하지 않습니다~ 왜냐구요?? 세마포어가 있으니까요 ㅋㅋ

바꿔서 생각해보면, 전경 배경 시스템에서 전역변수를 이용해서 세마포어 같은것을 하나 만들어놓고 사용하는 것이랍니다. ㅋㅋ

그냥 프로그램 하는 자기 자신과의 약속이지요~

"함수가 자원을 액세스 하기 전에는 꼭 정해놓은 전역변수를 점검하고 그 변수의 값이 0일때만 그 자원에 엑세스 하겠다. 1일때는 절대로 접근을 시도조차 하지 않겠다"

ㅋㅋㅋㅋ

자기들만의 리그를 뛰고 있는거지요  머 ㅋㅋㅋ 프로그램하다보면 저런 비슷한거 많이 찾아볼수 있습니다 ㅋㅋㅋ

TAS 를 사용할때는 TAS 오퍼레이션이 인터럽트에 의해 선점이 되면 안되겠지요?? 그말인 즉슨, 꼭 수행하기 전에 인터럽트를 비활성화 해야한다는 소리입니당. ㅋㅋㅋ

여기서도 간단히 Psudo Code 를 써보면요

if ( 액세스 변수가 0 이면 )
{
변수를 1로 세팅한다.
인터럽트를 활성화 한다.
자원을 액세스 해서 사용한다.
인터럽트를 비활성화 환다.
액세스 변수를 0으로 세팅한다.
인터럽트를 활성화 시켜놓는다.
}
else
{
인터럽트 활성화 시킨다.    // 즉 자원에 액세스를 할수없다. 나중에 다시 시도한다.
}


정도가 되겠군요 ㅋㅋ

(3) 스케쥴러 비활성화

뭐 다들 비슷한 개념입니다.

비 선점형 커널에는 크게 관계없는 방법이겠네요 ~

이 방법을 사용하기 위해서는 전제 조건이 하나 필요합니다.

" ISR 과는 공유자원을 공유하지 않는다."

이 전제조건을 만족해야만 스케쥴러를 비활성화 시키는 것으로 우리가 의도하는 바를 이룰수 있죠.

개념은 이렇습니다.

"ISR 로 뛸 테면 뛰어라. 어차피 ISR 과는 공유자원을 공유하지 않으니까 ISR 이 공유자원을 훼손할 일은 없고, ISR 이 끝나고 나서 일하고 있던 테스크로 무조건 다시 CPU 점유권을 넘겨줘 버릴테니까 !!!! "

ㅋㅋㅋ

어디서 많이 보던 개념 아닌가요???

그렇습니다!!! 비선점형 커널이 하는 짓거리 지요?? ㅋㅋ

이 방법도 이론적으로 잘 동작하기는 합니다. ㅋㅋ

하지만 사용하고 있는 커널이 선점형 커널이라면, 구지 다른 좋은 방법이 많은데요 Mutual Exclusion 을 구현하기 위해 커널 고유의 특성을 변경할 필요는 없지 않을까요?/ ㅋㅋㅋ

그래서 이 방법은 부득이한 상황이 아니면 사용하지 않는것이 좋습니다 ㅋㅋ

사실 Scheduler Lock / Unlock OS 관련 함수를 저는 본적이 없군용 ㅋㅋㅋㅋ

여튼 여기도 Psudo Code

스케쥴러 락
공유자원 엑세스
스케쥴러 언락


ㅋㅋㅋㅋㅋ 단순하군 ㅋㅋㅋㅋ (이렇게 쓰면 프로그래밍 해주는 컴파일러를 만들면 대박일텐데요 ㅋㅋ 그죠?? ㅋ )

(4) 세마포어의 이용

 아  ㅋㅋㅋ 쓰다보니 거의 다 왔군요 ㅋㅋ 세마포어 ~

1960년 중반에 Edgser Diikstra 에 의해 발명 되었답니다 ㅋㅋㅋ (이름이 왜 저따위냐 ㅋㅋ)



대부분의 멀티태스킹 커널이 제공하는 프로토콜 메커니즘 이구요 꼭 상호 배제를 위해서만 사용되는 것은 아닙니다.

ㄱ) 공유자원 간의 액세스 제어 (Mutual Exclusion)
ㄴ) 이벤트의 발생을 알려줌 (Signaling)
ㄷ) 두 태스크 간의 동작을 동귀화 시킴 (Synchronization / Rendezvous)

정도로 볼 수 있겠군요 ㅋㅋ

일단 여기서는 ㄱ) 의 상황에 대해서만 간단하게 언급해볼깝숑 ㅋㅋㅋ

세마포어는 어떤 자원에 접근하기 위한 '열쇠' 와도 같은 개념입니다.

이 열쇠를 1개만 만들어 놓으면 "Binary Semaphor" 혹은 "Mutex" 라고 부르구요

열쇠는 좀 복사를 많이 해 놔서 여러개 만들어 놓으면 "Counting Semaphore" 라고 부릅니다.

우리는 ㄱ) 의 상황을 논의해야하니까 Binary Semaphore 를 사용해야 겠네요?? ㅋㅋ

세마포어는 생성되고 나면 Send , Waiting 의 두가지 작업을 할 수 있습니다.
혹은 Post, Pend 라고 부르기도 하지요 ~ 뭐 같은 개념이니까요 ㅋㅋ

Send 를 하면 세마포어의 숫자는 + 하게 됩니다. Wait (Pend) 해서 세마포어를 받게 되면 숫자는 - 하게 되지요 ㅋㅋ

이 숫자가 코드를 돌릴수 있는 횟수와 정확하게 일치 합니다.

즉, 키를 하나만 만들어 놓는다면??  한번에 한놈씩만 공유자원에 접근할수 있겠지요???

시작이 1개였는데 ㅋㅋㅋ 5놈이 기다리고 있던 10놈이 기다리고 있던 제일 먼저 어떤놈이 키를 가져가 버리면
세마포어 숫자가 0으로 바껴서 나머지놈들은 끝없이 기다려야만 하는 상황이거든요 ㅋㅋ

사용하던놈이 자원을 다 쓰고 Send (Post) 해야 갯수가 1로 늘어나고 다음놈이 가져다 쓸수 있는 상화ㅘㅇ이 되는 것입니다.

세마포어의 생성은 되어있는 상태가 가정하고 Psudo Code 를 작성해 보지요

세마포어 Wait (Pend)
공유자원 엑세스
세마포어 Send(Post)

간단하지요? ㅋㅋㅋ
일단 이렇게 단순하게 생각하시고 나머지 개념들은 뒤에서 다시 추가하도록 하셔요 ㅋㅋ

한번에 너무 많이 알려면 머리가 아푸니까요 ㅋㅋㅋ (대가리가 뽀개지니까요 라고 자연스럽게 썼다가 포스팅의 질을위해 급 바껐습니다 ㅋㅋㅋ)

그럼 빠이
Posted by J.Bear