본문 바로가기
Programing_Language/C#

[쓰레드 동기화] Thread [Sleep, Yield] , ContextSwitching

by neohtux 2020. 7. 21.
728x90

랜덤(Random) 접근

스레드가 while 루프내에서 스핀 락 처럼 무한정 대기하며 불필요한 작업을 하는 것이아닌

랜덤적으로 접근하여 해장 잠금(locked)을 사용하는 방법이다.

 

여기서 랜덤적으로 접근이란, 한 가지 예시적 상황을 보자.

처음 들어온 스레드가 임계구역에 들어가서 어떤 변수를 사용중인 상황에

두번째 스레드가 임계구역에 들어 가려고 잠금을 획득하려는 찰나 누군가 사용하고 있다.

 

스핀 락의 경우 폴링방식으로 무한정 대기하지만,

 

이 랜덤 접근의 상황에서는 두번째 스레드가

"아 누군가 쓰고있네 잠시 있다 와야지 난 좀 이따가 올게 "의

방법이다. 이 방법을 사용하면 불필요한 연산이나 작업을 줄여 CPU의 점유율을 낮출 수 있지만,

 

반대로, "잠시 있다 와야지" 라는 상황이 무한정 발생한다면,

해당 스레드는 작업을 못하고 아사현상에 빠지게 된다.  

 

아사현상에 빠지는경우는 많은 경우가 있는데 대표적으로 우선순위에 계속 밀려서
해당 작업을 못하거나, 다른 프로세스들이 자신 들의 작업을 계속 잡고 있어

자신의 작업을 못하는 경우이다.

 

이 경우 에이징이나, 타임 슬라이스를 이용한 방식들이 있는데 이 또한 완벽한 방법은 아니다.

 

아래는

스레드 슬립을 이용한 우선순위 양보와, 휴식을 이용하여 불필요한 연산과 점유율을 낮추는 
기본적인 방법이다.

 

Thread.Sleep(1);

스레드 슬립을 1ms를 주어서 루프내에서 1ms 대기하는동안 만약 

해당 잡금 locked이 풀리면 루프를 탈출하여 자신이 그 일을 수행할 수 있다.

이건 무조건 1ms 의 휴식의 개념이다. 

(실제 정확히 1ms인지는 컴퓨팅에 따라 조금씩 다르다)

 

하지만, 만약 먼저온 스레드들이 작업을 10ms 이상 한다면 두번쨰 스레드는
아사 상태에 빠질 것이다.

 

 

Thread.Sleep(0);

스레드 슬림 0ms 는 조건부 잠금(자물쇠) 양보 개념이다.

 

누군가 잠금을 사용하고 있을때,

현재 남아있는 스레드들 중 자신보다 우선순위가 낮은 애들?(스레드)한테는 양보하지 않고

자신이 사용하는것이고 자신보다 높은 우선순위가 있으면 "그래 너가 먼저 해"의 개념이다.

 

하지만, 이경우도 계속해서 해당 잠금을 사용중인 스레드가 자신보다 우선순위가 높은 스레드들 밖에 없다면 우선순위가 변하지 않고 낮은 스레드는 아사 상태에 빠질 것이다.

 

 

 

Thread.Yield();

 

 

 

ContextSwitching

스레드를 양보하는 개념에서 쉽게 스레드 간에 얘기하며 "응 너가 먼저써 "  "지금 쓸수 있나? " 
이렇게 쉽게 양보하면 좋겠지만 현실은 그렇지 않다.

 

실제 해당 스레드 또는 프로세스의 일을 배정하고 감독하는것은 

결국 CPU코어와 운영체제 (대빵) 의 몫이기 떄문이다.

 

만약 위처럼 어떤 스레드가 도착하여 작업을 수행할때 누군가 먼저 쓰고있어서 양보해야하는 입장이라면

레지스터에서

"어떤 상태였는지, 어떤 작업을 진행중이였는지, 어떤 작업을 진행할것인지, 필요한 자원들은 뭐였는지 기억하고 있었다면" (이러한 내용을 Context라고 부르겠음.)

 

이 작업들을 다시 레지스터에서 결국 메인 메모리에 다시 올려놓고

다음 순서의 스레드의 작업내용과 내용(Context)를 레지스터에 올려야하는 작업은

커널 입장에서 굉장히 부담스러운 일이다.

 

조금 쉽게 예를 설명하면

주방에서 냉장고에서 온갖 채소들과 식료품을 꺼내 작업을 하려는데

이미 주방에서 누군가 돼지고기를 썰며 작업을 진행중이면, 다시그 온갖 채소들과 식료품을
냉장고 문을열고 다시 넣고 냉장고 공간을 재배치하고 문을 닫는 행위가 되는 것이다.

 

 

 

 

 

 

300x250

댓글