728x90
반응형
1. 신호에 의한 쓰레드 동기화
이전까지 배운 쓰레드 동기화들은
[c#] 쓰레드 동기화 클래스 1(Lock, Monitor)
[c#] 쓰레드 동기화 클래스 2(Mutex, Semaphore)
공유 되는 리소스에 락을 걸어서 쓰레드 접근을 제한했다.
하지만 지금 배울 것은 대기중인 쓰레드에 신호를 보내어 쓰레드 흐름을 통제하는 방식이다.
많이 사용되는 방식에는 AutoResetEvent, ManualResetEvent, CountdownEvent, Wait/pulse 등이 있다.
* 여기서 Event는 윈도우 프로그래밍에서 말하는 event와 다른 개념 = 쓰레드 동기화에 사용되는 OS리소스이다.
2. AutoResetEvent
using System;
using System.Threading;
namespace ThreadSafe
{
class Program
{
private static AutoResetEvent autoEvt = new AutoResetEvent(false);
static void Main(string[] args)
{
Thread thrd = new Thread(Run);
thrd.Name = "A Thread";
thrd.Start();
Thread.Sleep(3000); // 3초 대기
autoEvt.Set();
}
private static void Run()
{
string name = Thread.CurrentThread.Name;
Console.WriteLine(name + " is Start");
autoEvt.WaitOne();
Console.WriteLine(name + " is ReStart");
Console.WriteLine(name + " is End");
}
}
}
결과 값
쓰레드가 생성되고 Run메서드 작업이 시작된다. 하지만 waitOne()에서 신호대기를 한다.
그럼 메인쓰레드가 Thread.Sleep(3000) = 3초 대기를 하고 Set()을 하면 신호대기를 하던 쓰레드가 다시 시작된다.
3. ManualResetEvent
AutoResetEvent는 하나의 쓰레드만 통과시키고 닫고 한다.
ManualResetEvent는 한번 열리면 대기중이던 모든 쓰레드가 실행하게 된다. 코드에서 수동으로 Reset()을 호출하여 문을 닫고 이 후 도착한 쓰레드들을 다시 대기토록 한다.
using System;
using System.Threading;
namespace ThreadSafe
{
class Program
{
private static ManualResetEvent manualEvt = new ManualResetEvent(false);
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
new Thread(Run).Start(i);
}
Thread.Sleep(3000);
manualEvt.Set(); // 10개의 쓰레드 모두 실행!
}
private static void Run(object number)
{
Console.WriteLine(number + " in Wait");
// 신호대기
manualEvt.WaitOne();
Console.WriteLine(number + " is End");
}
}
}
결과 값
4. CountdownEvent
한 쓰레드에서 여러개의 쓰레들로부터의 신호를 기다리는데 사용된다.
using System;
using System.Threading;
namespace ThreadSafe
{
class Program
{
private static CountdownEvent countEvt = new CountdownEvent(5);
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
new Thread(Run).Start(i);
}
// 메인쓰레드 첫 5개 신호를 기다림
countEvt.Wait();
Console.WriteLine("All Thread is done!");
}
private static void Run(object number)
{
if (countEvt.CurrentCount > 0)
{
countEvt.Signal(); // CurrentCount을 1씩 줄이면서 신호를 등록
Console.WriteLine(number + " here");
}
else
{
Console.WriteLine(number + " there");
}
}
}
}
결과 값
참고
728x90
반응형
'프로그래밍 > c#' 카테고리의 다른 글
[c#] 프로그램 시작시 중복 체크 (0) | 2021.01.12 |
---|---|
[c#] STAThread/COM(Component Object Model) (0) | 2021.01.12 |
[c#] 쓰레드 동기화 클래스 2(Mutex, Semaphore) (0) | 2019.10.08 |
[c#] 쓰레드 동기화 클래스 1(Lock, Monitor) (0) | 2019.10.08 |
[c#] Thread Safe (쓰레드 동기화) (0) | 2019.10.08 |
댓글