728x90
반응형
1. Unsafe Method : 쓰레드 동기화를 하지 않은 메서드
using System;
using System.Threading;
namespace ThreadSafe
{
class Program
{
private static int baby = 0;
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
new Thread(CountBaby).Start();
}
}
private static void CountBaby()
{
baby++;
Console.WriteLine(baby);
}
}
}
2. Lock
using System;
using System.Threading;
namespace ThreadSafe
{
class Program
{
private static int baby = 0;
private static object lockObj = new object();
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
new Thread(CountBaby).Start();
}
}
private static void CountBaby()
{
lock (lockObj)
{
baby++;
Console.WriteLine(baby);
}
}
}
}
lock을 사용하는 방법은 object타입으로 전역변수를 만들어주고 필요한 곳에 lock { } 구문을 넣어주면 끝!
결과 값
3. Monitor
Lock과 거의 비슷하다. 대신 Monitor.Enter(obj), Monitor.Exit(obj) 를 이용한다.
using System;
using System.Threading;
namespace ThreadSafe
{
class Program
{
private static int baby = 0;
private static object lockObj = new object();
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
new Thread(CountBaby).Start();
}
}
private static void CountBaby()
{
Monitor.Enter(lockObj);
try
{
baby++;
Console.WriteLine(baby);
}
finally
{
Monitor.Exit(lockObj);
}
}
}
}
정상적인 Exit를 위해 try~finally를 이용하여 감싸준다.
결과는 Lock과 같다.
Monitor에는 wait(), pulse(), pulseAll() 이란 메서드가 있다.
wait() : 현재 쓰레드를 잠시 중단시키고, lock을 푼다. 다른 쓰레드로 pulse() 신호가 올 때까지 대기한다.
다른 쓰레드들 중 하나는 lock을 획득하여 작업을 실행한다. 작업이 끝난후 pulse()메서드를 호출하면 대기중인 쓰레드는 lock을 획득하여 작업을 실행한다.
이 메서드들은 lock 블럭 안에서 실행되어야한다.
using System;
using System.Threading;
namespace ThreadSafe
{
class Program
{
private static int baby = 0;
private static object lockObj = new object();
static void Main(string[] args)
{
Thread anotherThrd = new Thread(AnotherCountBabyMethod);
anotherThrd.Start();
for (int i = 0; i < 10; i++)
{
new Thread(CountBaby).Start();
}
}
private static void AnotherCountBabyMethod()
{
lock (lockObj)
{
if (baby == 0) Monitor.Wait(lockObj);
Console.WriteLine(baby);
}
}
private static void CountBaby()
{
lock (lockObj)
{
baby++;
Console.WriteLine(baby);
Monitor.Pulse(lockObj);
}
}
}
}
anotherThrd를 통해 AnotherCountBabyMethod() 메서드에 스레드가 접근했다가 wait() 때문에 대기한다.
그 뒤 for문의 첫번째 생성 쓰레드가 CountBaby() 메서드를 작업하다가 pulse() 를 만나 대기된 쓰레드를 풀어준다.
그래서 결과 값은 1이 두 번 찍히는 결과를 보여준다.
Mutex, Semaphore를 다 정리하려 했지만 글이 길어져 다음 글에 이어서 하겠다.
[c#] 쓰레드 동기화 클래스 2(Mutex, Semaphore)
참고
728x90
반응형
'프로그래밍 > c#' 카테고리의 다른 글
[c#] 쓰레드 동기화 클래스 3(AutoResetEvent, ManualResetEvent, CountdownEvent) (0) | 2019.10.08 |
---|---|
[c#] 쓰레드 동기화 클래스 2(Mutex, Semaphore) (0) | 2019.10.08 |
[c#] Thread Safe (쓰레드 동기화) (0) | 2019.10.08 |
[c#] 이벤트(event)와 델리게이트(delegate) (0) | 2019.10.08 |
[Tip] 프로그램 소스코드를 공개하는 사이트 모음집 (0) | 2019.10.02 |
댓글