Coding Memo

[메모] C++ ReadWriteLock 데드락 문제 본문

메모

[메모] C++ ReadWriteLock 데드락 문제

minttea25 2024. 4. 26. 16:20

ReadWriteLock의 특징은 다음과 같다.

1. Spinlock으로 구현

2. unsigned int 값의 flag를 하나 지정하여, 상위 2바이트는 write중인 thread_id, 하위 2바이트는 현재 read중인 스레드의 수를 나타냄

3. thread_id는 thread가 새로 시작할 때 id 부여

4. write 중일 때는 다른 스레드들이 이 lock을 얻지 못함

5. wrtie 중이 아닐 때는 다수의 스레드가 동시에 read 가능

6. EMPTY_FLAG (어느 스레드도 lock을 가지고 있지 않을 경우)는 0x00000000

 

서버-클라이언트의 연결에서 가끔씩 패킷을 전송 할 때, 세션의 전송 함수 내의 WRITE_LOCK에서 spin-timeout이 나타났다. 즉, deadlock이다.

 

이번 문제의 경우에는 어떤 스레드가 lock을 제대로 release하지 않아서 나온 문제가 아니었다. 겉으로볼 때는 deadlock이긴하지만, 내부는 조금 다른 느낌이었다.

 

전송을 담당하는 메인스레드의 thread_id값이 0이었기 때문에 다른 스레드들이 해당 lock을 가지고 있지 않아도 혼자서 락을 얻을 수가 없는 상황이 생겨버려서 일어난 문제였다.

 

thread_id가 0이면 writelock을 얻었더라도 flag가 0x00000000 이 되기 때문이었다.

thread_id 발급을 1부터 시작으로 바꾸어서 해결했다.

 

구현한 코드를 올바르게 사용하자.

에러를 찾을 때, 가장 높은 확률로 문제라고 생각되는 부분이 때로는 문제가 없을 수도 있다. 이런 상황에서는 문제가 없는 코드를 계속 보지말고, 다른 부분에 눈을 돌려서 문제를 확인해보자.