Lock을 누가 점유하고 있다면?
1) 무작정 기다린다. => SpinLock
2) 나중에 다시 시도한다. (랜덤성) => 쓰레드가 자기 소유권을 포기 Context Switching
3) 운영체제의 도움을 받는다. AutoResetEvent
무조건 휴식 -> 무조건 1ms 정도 쉬고 싶어요
조건부 양보 => 나보다 우선순위가 낮은 애들한테는 양보 불가
=> 우선순위가 나보다 같거나 높은 쓰레드가 없으면 다시 본인한테
관대한 양보 => 관대하게 양보할테니, 지금 실행이 가능한 쓰레드가 있으면 실행하세요
=> 실행 가능한 애가 없으면 남은 시간 소진
SpinLock보다는 무한정으로 루프를 도는 일을 줄일 수 있다.
using System;
using System.Threading;
namespace SeverCore
{
class SpinLock
{
volatile int _locked = 0;
public void Acquire()
{
while (true)
{
// CAS Compare-And-Swap
int expected = 0;
int desired = 1;
if(Interlocked.CompareExchange(ref _locked, desired, expected) == expected)
break;
Thread.Yield();
}
}
public void Release()
{
_locked = 0;
}
}
class Program
{
static int _num = 0;
static SpinLock _lock = new SpinLock();
static void Thread_1()
{
for (int i = 0; i < 100000; i++)
{
_lock.Acquire();
_num++;
_lock.Release();
}
}
static void Thread_2()
{
for (int i = 0; i < 100000; i++)
{
_lock.Acquire();
_num--;
_lock.Release();
}
}
static void Main(string[] args)
{
Task t1 = new Task(Thread_1);
Task t2 = new Task(Thread_2);
t1.Start();
t2.Start();
Task.WaitAll(t1, t2);
Console.WriteLine(_num);
}
}
}
Context Switching이 반드시 좋은 것은 아니다.
일감을 바꿔치기할 때마다 많은 부담이 들기 때문에!