using System;
using System.Threading;
using System.Threading.Tasks;
/// <summary>
/// deadLock
///
//
/// </summary>
namespace ServerCore
{
/// <summary>
/// 존버매타
///
///
///
/// </summary>
class SpinLock
{
/// volatile 가시성 보장!
/// 가시성이 뭔지 다시 보기!
volatile int _locked = 0;
public void Acquire()
{
///이렇게 그냥 사용하면
///Interlocked.Exchange(ref _locked, 1);
///_locked = 1; ///이거랑 다를바 없음
while (true)
{
int original = Interlocked.Exchange(ref _locked, 1);///return original value 하기때문에 리턴값을보고 우리가 바꿧는지 아니면 다른데서 사용해서 바뀐건지 확인 할 수 있음
if (original == 0)
{
///아무도 없을때 !
break;
}
{
///싱글스레드 였을때의 표현
///하지만 멀티에서는 먹히지않는다!
///두번 만에 진행되기때문에!(원자성문제)
int ori = _locked;
_locked = 1;
if (ori == 0)
break;
}
{
if (_locked == 0)
_locked = 1;
}
}
///이 부분이 한번에 처리 안되서 문제
///두개 동시에 와일을 탓을때가 문제다!
/*while (_locked)
{
/// 잠김이 풀리기를 기다린다.
}
_locked = true;
///내꺼!*/
///do something...
}
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 < 10000; i++)
{
_lock.Acquire();
_num++;
_lock.Release();
}
}
static void Thread_2()
{
for (int i = 0; i < 10000; 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);
}
}
}
using System;
using System.Threading;
using System.Threading.Tasks;
/// <summary>
/// deadLock
///
//
/// </summary>
namespace ServerCore
{
/// <summary>
/// 존버매타
///
///
///
/// </summary>
class SpinLock
{
/// volatile 가시성 보장!
/// 가시성이 뭔지 다시 보기!
volatile int _locked = 0;
public void Acquire()
{
///이렇게 그냥 사용하면
///Interlocked.Exchange(ref _locked, 1);
///_locked = 1; ///이거랑 다를바 없음
while (true)
{
/*int original = Interlocked.Exchange(ref _locked, 1);///return original value 하기때문에 리턴값을보고 우리가 바꿧는지 아니면 다른데서 사용해서 바뀐건지 확인 할 수 있음
if (original == 0)///아무도 없을때 !
break;*/
/// CAS Compare-And-Swap
/// if(_locked==0)
/// _locked=1; 이런느낌
int expected = 0;///예상한값(lock걸리기 전)
int desired = 1;///예상한값이 맞다면 넣어야할값(lock걸기)
///뺑뺑이 돌면서 획득할때까지 돌리기
if(Interlocked.CompareExchange(ref _locked, desired, expected) == expected)
break;
}
///이 부분이 한번에 처리 안되서 문제
///두개 동시에 와일을 탓을때가 문제다!
/*while (_locked)
{
/// 잠김이 풀리기를 기다린다.
}
_locked = true;
///내꺼!*/
///do something...
}
public void Release()
{
///이미 문을 열어놨기 때문에 이 변수 write하는거에 대해서 문제 될 것이 없다!!
_locked = 0;
}
}
class Program
{
static int _num = 0;
static SpinLock _lock = new SpinLock();
static void Thread_1()
{
for (int i = 0; i < 10000; i++)
{
_lock.Acquire();
_num++;
_lock.Release();
}
}
static void Thread_2()
{
for (int i = 0; i < 10000; 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);
}
}
}
댓글 없음:
댓글 쓰기