[C#] Thread 쓰레드 동기화C#/C#정리2021. 9. 28. 20:14
Table of Contents
사용 이유
- 멀티 스레드는 실행 순서가 불규칙하다.
- 공유 리소스(shared resource)에 대한 스레드의 동기화(synchronization)처리가 되지않았다.
Monitor : 모니터
Enter와 Exit 코드 사이에 위치한 모든 코드는 한 순간에 스레드 하나만 진입해서 실행할 수 있다.
또한 Enter와 Exit 메서드의 인자로 전달하는 값은 반드시 참조형 타입의 인스턴스여야 한다.
private static object lockObj = new object();
Monitor.Enter(lockObj);
try
{
~~~
}
finally
{
Monitor.Exit(lockObj);
}
* Wait(lockObj) / Pulse(lockObj) / PulseAll(lockObj)
Lock : 스레드 락
부가적으로 C#언어에서는 try/finally + Monitor.Enter/Exit 코드와 동일한 역할을 하는 lock예약어를 제공한다.
구문은 바뀌었지만 C#컴파일러에 의해 최종적으로는 코드변환이된다.
대개의 경우 코드가 간결하다는 이유로 lock예약어를 이용한 구문이 더 선호된다.
private static object lockObj = new object();
lock(lockObj)
{
~~~
}
Mutex 뮤텍스
프로세스 간에 Locking 할 때, 느려서 프로세스 내에서 할때는 위 1,2 번 방식 사용
// bool값 = 호출 스레드가 뮤텍스의 초기 소유권 가질지
using(Mutex mutex = new Mutex(false, "MuteName"))
{
mutex.WaitOne();
~~~
mutex.ReleaseMutex();
}
//Release 안할 경우 대비해서
if(mutex.WaitOne(1000))
{
~~~
}
else ~~~ // 1초 지나도 취득 안될경우 할 일.
Semaphore 세마포어
여러개. 이것도 프로세스간 사용 가능.
// n = 처음 요청 개수, m= 최대 요청 개수.
private static Semaphore sema = new Semaphore(n, m)
sema.WaitOne(); // 이 이후 m개만 들어올 수 있음.
sema.Release(m) // m개를 놔줌(or 수행). () 하면 1개 놔
AutoResetEvent
Set 하면, 하나 이상의 대기중 스레드 중 첫번째로 대기 시작한 쓰레드 하나를 진행시킴.
private static AutoResetEvent autoEvt = new AutoResetEvent(false); // 초기상태 신호 받음 설정 여부.
autoEvt.WaitOne();
autoEvt.Set();
ManualResetEvent
위에랑 달리 Set 1회에 모든 대기중 쓰레드 진행시킴.
private static ManualResetEvent manualEvt = new ManualResetEvent(false);
manualEvt.WaitOne();
manualEvt.Set();
CountdownEvent
카운트를 1개씩 줄임.
private static CountdownEvent countEvt = new CountdownEvent(5);
countEvt.Signal(); 하면 카운트 하나 줄어든다.
countEvt.IsSet() or countEvt.CurrentCount > 0 이런식으로 if문에 넣어서 사용하면 된다.
반응형
'C# > C#정리' 카테고리의 다른 글
[C#] GC, 가비지 컬렉터, 메모리 관리, using (0) | 2021.09.28 |
---|---|
[C#] 관리되는, 관리되지 않는 코드 (0) | 2021.09.28 |
[C#] Thread 쓰레드 (0) | 2021.09.28 |
[C#] 다양한 타입(object, dynamic, var) (0) | 2021.09.28 |
[C#] 메소드 오버로드 (0) | 2021.09.20 |
@반나무 :: 반나무_뿌리
3년차 WPF 개발자입니다.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!