• 카테고리

    질문 & 답변
  • 세부 분야

    게임 프로그래밍

  • 해결 여부

    미해결

안녕하세요 선생님 Thread.Yeild(); 에 대해서 질문 합니다.

21.02.12 02:09 작성 조회수 176

0

            while(true)

            {

                int expected = 0;

                int desired = 1;

                if (Interlocked.CompareExchange(ref _locked, desired, expected) == expected)

                    break;

                Thread.Yield();    

            }

이 코드를 정리를 해보면 

만약에 A 쓰레드가 있고, B쓰레드가 있다

A쓰레드가 공유 자원을 점유하고 있으면

lock이 0에서 1로 바뀌고 

B 쓰레드는 접근 하려니까 lock이 1이니까 계속 무한 루프를

돈다. 이것은 성능상의 저하를 불러 일으킨다.

왜? 쓸데없는 행동이기 때문에 따라서

A쓰레드가 공유자원을 사용을 끝날 때 까지

B쓰레드를 무한루프를 돌게 하지말고 재우는데

Thread.sleep, yeild.. 뭐 이런 함수를 이용해서

재우는데

그럼 무한 루프가 잠시 멈추는 상황이잖아요?

그럼 a쓰레드가 공유자원을 쓰고 나왔다는 것을

어떻게 알 수 있나요? 검색 해보니까 sleep을 os가 깨운다는데

그럼 정리를 해보면 면접관님 께서 만약 이런 질문을 하시면

일단 OS가 A 쓰레드가 할일을 끝냈으니, 잠자고 있던

B쓰레드를 깨워서 그때부터 반복을 해서 다시 LOCK 검사를

진행합니다.

LOCK 변수 값이 0이라면 컨텍스트 스위칭이 일어나는데

A 쓰레드의 정보가 레지스터에서 지워지고 B 쓰레드 정보가

채워짐으로써 B 쓰레드가 CPU를 점유하고 이제 B쓰레드가

공유자원  _num변수를 사용해서 _num++연산이 진행이

됩니다.  이렇게 저는 해당 챕터 강의를 이해 하고 정리를 했거

든요 혹시 틀린 점이 있다면 알려주심 감사하겠습니다.

아 그 sleep 걸어놓고 os가 깨우는 거 맞는지도 알려주시면

감사하겠습니다. ^^

답변 1

답변을 작성해보세요.

0

그럼 a쓰레드가 공유자원을 쓰고 나왔다는 것을
어떻게 알 수 있나요? 검색 해보니까 sleep을 os가 깨운다는데

-> 물론 알 수 없습니다.
비행기 화장실에서 누가 있으면 그냥 자리에 앉았다가 

대충 5분 후 다시 오는 느낌으로,
잠시 한숨 자고 (Sleep) 오는 것이죠. (강의에서 '랜덤 메타'라 표현한 것)
정말 알고 싶으면 Event를 이용해서 A->B 통보하는 방식이 있지만
이는 커널 자원을 추가로 사용하는 것입니다. (강의에서 '갑질 메타'라 표현한 것)

일단 OS가 A 쓰레드가 할일을 끝냈으니, 잠자고 있던
B쓰레드를 깨워서 그때부터 반복을 해서 다시 LOCK 검사를 진행합니다.

-> 말씀하신건 Event 방식의 동기화입니다.
현재는 그냥 OS가 일정 시간이 지나면 깨우고,
그 때 다시 한 번 Lock 검사를 시도하는 것이죠.

아 그 sleep 걸어놓고 os가 깨우는 거 맞는지도 알려주시면 감사하겠습니다. ^^

-> Sleep 한다고 영구적으로 잠자는 것은 아닐테고,
당연히 누군가는 깨워줄텐데 그것은 OS의 역할이 맞습니다.
원래 OS가 프로세스마다 실행할 시간 (timeslice)를 할당해주는데,
경우에 따라 프로세스가 sleep yield 등을 통해
그 정당한 권리를 한 턴 포기한다고 보시면 됩니다.
그러면 다음 턴에서 OS가 깨워서 또 실행을 해주겠죠.