📄 ReaderWriterLock
상호배제를 위한 기능은 동일하지만, 데이터에 대해 읽기, 쓰기에 대한 호출의 비율이 매우 편중되어있을 때 적합한 방법입니다.
예를들어 플레이어들이 서버로부터 아이템을 보상을 받는다고 할때 플레이어는 단순히 서버로부터 획득할 아이템 정보를 읽으면 됩니다. 읽는것만으로는 큰 문제가 되지 않습니다. 이 상태에 일반적인 Lock을하여 읽는것에대해 상호배제를 적용한다면 아쉬운 성능을 보여줄 수 있습니다. 서버 관리자가 가끔씩 보상 아이템을 설정하기위해 쓰기를 하는 경우를 들었을때 플레이어들이 읽는것에 비해 빈도가 아주 적게 일어나 아주 가끔씩 Lock을해야하는 경우 이 방법을 사용하면 더욱 효과적입니다.
📑 ReaderWriterLockSlim
namespace ServerCore
{
public class Reward
{
//퀘스트 보상으로 주어지는 아이템 등.
}
class Program
{
//읽는 행위에 대해서는 락을 하지 않지만, 가끔식 일어나는 쓰기에 대해 상호배제를 보장하기 위한 기능
private static ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim();
//보상을 얻기위해 읽는 행위는 매번 일어남
private static Reward GetRewardById(int id)
{
rwLock.EnterReadLock();
//do Something...
rwLock.ExitReadLock();
return null;
}
//쓰기를 위한 행위는 아주 가끔씩 일어남
private static void AddReward(Reward reward)
{
rwLock.EnterWriteLock();
//do Something...
rwLock.ExitWriteLock();
}
}
}
private static void AddReward(Reward reward)
- 서버관리자가 AddReward로 Reward를 추가하기위해서 새로운 데이터를 써야하는 상황입니다.
- 서버관리자는 데이터를 덮어쓰기때문에 EnterWriteLock을 사용하여 락을 설정합니다.
- 이 상태에서 Read를 하기위한 GetRewardById(..)에서 진입이 불가능해집니다.
private static Reward GetRewardById(int id)
- 플레이어가 아이템을 획득하기위해 서버에 요청하여 아이템 정보를 얻어옵니다.
- EnterReadLock()은 EnterWriteLock()이 활성화 되어있을때 접근이 불가능해집니다.
- EnterWriteLock()이 활성화되어 있지 않은 상태에서는 자유롭게 접근이 가능합니다
- '읽기' 작업을 하는 스레드들 사이에서는 서로 방해를 하지 않습니다.
'server > socket server' 카테고리의 다른 글
[C# 서버] Thread Local Storage (0) | 2023.01.12 |
---|---|
[C# 서버] ReaderWriterLock 구현 (0) | 2023.01.11 |
[C# 서버] Mutex (0) | 2023.01.09 |
[C# 서버] AutoResetEvent (1) | 2023.01.06 |
[C# 서버] Context Switching (0) | 2023.01.04 |