[C#] ReaderWriterLock

수민·2023년 6월 6일
0

게임서버 이론

목록 보기
4/6
post-thumbnail

인프런 강의 를 듣고, 개인 공부 목적으로 정리한 글입니다.


ReaderWriterLock의 개념

Read는 많이 하는데 Write의 빈도가 너무 작아서,,
매번 Mutex를 하기엔 부담인 경우도 있다.

그럴 때 ReadWriteLock을 사용하면 좋겠다.

뭐냐면
WriteLock이 없으면 Read는 동시다발적으로 접근할 수 있다.
단, WriteLock이 있다면 Read 불가.

즉,
ReadLock은 여러 번 불릴 수 있다.
단, WriteLock -> ReadLock = X

여기서 만약 재귀적 Lock을 허용한다면
WriteLock -> WriteLock : OK
WriteLock -> ReadLock : OK
ReadLock -> WriteLock : X

이론은 이렇다.


구현

32bit int 자료형으로 flag 변수를 이용한다.
[Unused(0)] [WriteThreadID(15)] [ReadCount(16)]

Unused : 최상위 비트는 음수가 될 가능성이 있으니 사용하지 않고,
WriteThreadID : WriteLock을 건 쓰레드의 ID
(재귀적 Lock을 허용할 경우 누가 Write를 잡고 있는지 확인해야 함)
ReadCount : ReadLock에 접근한 쓰레드의 개수

5000번 spin하고 안되면 Yield한다 (spinlock)

동작 원리

재귀적 lock을 허용한다는 가정.

WriteLock

만약 WriteThreadID가 현재 쓰레드 ID라면 WriteCount를 늘리고 리턴 (재귀적 락)

아니라면,
WriteThreadID가 0임을 확인한다.
만약 flagWriteThreadID가 0이라면 writeCount를 1로 만들고 리턴

WriteUnlock

writeCount가 0이라면 flag를 0으로 싹 밀어준다.
(WritLock하면 ReadLock도 접근 불가능하므로)

만약 WriteCount가 0이 아니라면 --WriteCount하면 됨

ReadLock

만약 WriteThreadID가 현재 쓰레드 ID라면 flag를 늘리고 리턴 (재귀적 락)

만약 flagWriteThreadID가 0이라면 ReadCount를 1 늘려준다.

ReadUnlock

flag를 1 줄여준다.


비트 연산

기본 연산


88

88 << 3

704 >> 2

참고

const int EMPTY_FLAG = 0x00000000;
const int WRITE_MASK = 0x7FFF0000;
const int READ_MASK = 0x0000FFFF;

앞서 말했듯,

이렇게 된다고 쳤을 때
WriteThreadID에 대한 값을 위해
WRITE_MASK는 상위 15개의 비트에 대해, 나머지는 다 0이어야 한다

이렇게 정해줘야
다른 값들과 AND 연산해서 비교할 수 있다.
그래서 WRITE_MASK는 0x7FFFF0000

READ_MASK도 동일한 방식이다.

profile
우하하

0개의 댓글