728x90
Rock처리와 함께사용
레이스컨디션
아래와 같은 소스코드를 실행할 경우 결과값은 0이아닌 다른 다양한 수로 출력된다. 이를 레이스 컨디션이라고 한다.
number ++를 할경우 보여지기에는 한 단계로 진행될 것 같지만 사실 어셈블리상으로는 아래 소스와 같이 3단계로 나뉘어 지기 때문에 0이아닌 결과가 나타나게된다.
static int number =0;
static void Thread_1()
{
for (int i = 0; i < 100000; i++)
{
//number++;를 어셈블리어로 풀어서 본다면 아래 소스와 같다.
int temp = number;
temp += 1;
number = temp;
}
}
static void Thread_2()
{
for (int i = 0; i < 100000; i++)
{
// number--;를 어셈블리어로 풀어서 본다면 아래 소스와 같다.
int temp = number;
temp -= 1;
number = temp;
}
}
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(number);
}
Interlocked을 사용하면 원자성을 보존할 수 있다.
성능이 빠르고 우수하나 정수만 사용할 수 있다는 단점이 존재한다. 또 한 몇십 몇백줄을 다 인터락을 사용해서 만들기 힘들다.
Increment - 1씩 증가
Decrement - 1씩 감소
static void Thread_1()
{
for (int i = 0; i < 100000; i++)
{
Interlocked.Increment(ref number);
}
}
static void Thread_2()
{
for (int i = 0; i < 100000; i++)
{
Interlocked.Decrement(ref number);
}
}
CompareExchange - 예상값 결과 값을 비교
while (true)
{
int expected = 0;//예상값
int desired = 1;//결과값
//첫인자랑 세번째인자와 비교한후 가운데 인자로 반납한다. 즉시 반납 아님 다음 루프때 _locked에 값 적용
if(Interlocked.CompareExchange(ref _locked, desired, expected) == expected)
break;
}
Exchange - 2번쨰 인자 값으로 _flag값 변경
Interlocked.Exchange(ref _flag, EMPTY_FLAG);
728x90
'VisualStudio > C#서버' 카테고리의 다른 글
[C#서버][개념] Thread.sleep 종류 (0) | 2022.10.26 |
---|---|
[C#서버][개념] 임계영역 Spin락(스핀락(SpinLock)) (0) | 2022.10.26 |
[C#서버][개념] 메모리 베리어( Memory Barrier) (0) | 2022.10.26 |
[C#서버][개념] volatile을 사용해 어셈블리 최적화 막기 (0) | 2022.10.26 |
[C#서버][기초] Thread & ThreadPool & Task (0) | 2022.10.26 |