VisualStudio/C#서버

[C#서버]임계영역과 SleepLock(컨텍스트스위칭)

usingsystem 2022. 10. 26. 15:43
728x90

Context Switching

컨텍스트 스위칭(Context Switching)은 운영 체제에서 실행 중인 여러 프로세스나 스레드 간에 실행을 전환하는 작업을 말합니다. 이러한 전환은 CPU가 한 작업에서 다른 작업으로 전환되는 과정을 포함합니다.

프로세스나 스레드는 실행을 위해 CPU를 사용하며, 한 프로세스나 스레드가 실행되고 있는 동안에도 다른 프로세스나 스레드로 전환될 수 있습니다. 이러한 전환은 여러 이유로 발생할 수 있습니다.

  1. 시분할(Time Slicing): 운영 체제는 CPU 시간을 여러 프로세스나 스레드에게 나누어 주어 각각에게 일정 시간 동안 실행할 기회를 부여합니다. 이 시간이 지나면 다른 프로세스나 스레드로 컨텍스트 스위칭이 발생합니다.
  2. 인터럽트(Interrupt): 하드웨어 인터럽트나 소프트웨어 인터럽트가 발생하면, 현재 실행 중인 작업이 중단되고 인터럽트 처리를 위한 코드가 실행됩니다. 이후에는 다시 이전 작업으로 복귀하게 되는데, 이것 또한 컨텍스트 스위칭을 포함합니다.
  3. 대기 상태로의 전환: 프로세스나 스레드가 어떤 이벤트가 발생하기를 기다리는 동안 대기 상태에 있을 수 있습니다. 이 이벤트가 발생하면 대기 상태의 프로세스나 스레드가 실행 상태로 전환되면서 컨텍스트 스위칭이 발생합니다.

컨텍스트 스위칭은 비용이 큰 작업 중 하나입니다. 이는 현재 실행 중인 프로세스나 스레드의 상태를 저장하고, 새로운 프로세스나 스레드의 상태를 복원하는 작업이 필요하기 때문입니다. 따라서, 효율적인 컨텍스트 스위칭은 시스템의 성능에 중요한 영향을 미칩니다.

멀티태스킹 환경에서 컨텍스트 스위칭은 여러 작업을 동시에 실행하는 데 있어서 중요한 역할을 합니다.

소유권 포기후 다시접근하는 방법으로 SpinLock에서 어떠한 조건을 추가한 형태이다.

아래코드에서는 Yield라는 우선순위 조건을 추가하여 구현되어있다.

 

단점 - 컨텍스트 스위칭은 쓰레드가 자원을 양보하고 새로운 쓰레드가 들어오면서 발생하는 많은 자원이 발생한다 

(레지스터의 종류에 따른 정보등)

Sleep

sleep 함수는 프로세스나 스레드의 실행을 지정된 시간 동안 멈추게 합니다. 이는 주로 일시적인 대기 상태를 만들어 다른 작업에 CPU를 양보하거나, 특정 조건이 충족될 때까지 대기하는 데 사용됩니다.

    class SpinLock
    {
        volatile int _locked = 0;
        public void Acauire()//획득
        {
            while (true)
            {
                int expected = 0;//예상값
                int desired = 1;//결과값
                if(Interlocked.CompareExchange(ref _locked, desired, expected) == expected)//첫인자랑 세번째인자와 비교한후 가운데 인자로 반납한다.
                    break;

                //Thread.Sleep(1);//무조건 1ms 쉰다.
                //Thread.Sleep(0);//조건부 양보 나보다 우선순위가 낮은 애들한테는 양보 불가 => 우선순위가 나보다 같거나 높은 쓰레드가 없으면 다시 자기자신 실행
                //                //우선순위낮은 쓰레드는 기아현상 발생가능
                Thread.Yield();//관대한 양보 => 관대하게 양보할테니 지금 실행이 가능한 쓰레드가 있으면 실행해라 => 실행 가능한 애가 없으면 남은 시간 소진
            }
        }
        public void Release()//반납
        {
            _locked = 0;
        }
    }

 

Thread.Sleep(1)

무조건 1ms 쉰다.

Thread.Sleep(0)

조건부 양보 나보다 우선순위가 낮은 애들한테는 양보 불가 => 우선순위가 나보다 같거나 높은 쓰레드가 없으면 다시 자기자신 실행우선순위낮은 쓰레드는 기아현상 발생가능

Thread.Yield()

관대한 양보 => 관대하게 양보할테니 지금 실행이 가능한 쓰레드가 있으면 실행해라 => 실행 가능한 쓰레드가 없으면 남은 시간 자신에게 소진

728x90