CRITICAL_SECTION에 이어 Windows에서 제공하는 유저 동기화 객체인 SRW_LOCK의 동작에 대해서 몇 가지만 기록한다..
typedef struct _RTL_SRWLOCK {
PVOID Ptr;
} RTL_SRWLOCK, *PRTL_SRWLOCK;
정의되어 있는 SRWLOCK은 단지 void* 변수 하나를 의미한다.
#include <iostream>
#include <Windows.h>
#include <thread>
SRWLOCK srw;
#include <iostream>
#include <Windows.h>
#include <thread>
#include <vector>
SRWLOCK srw;
void ThreadFunc()
{
AcquireSRWLockExclusive(&srw);
std::cout << " 실행" << std::endl;
ReleaseSRWLockExclusive(&srw);
}
int main()
{
InitializeSRWLock(&srw);
AcquireSRWLockExclusive(&srw);
std::vector<std::thread> tv;
for (int i = 0; i < 2; i++)
{
tv.push_back(std::thread(ThreadFunc));
}
Sleep(2000);
ReleaseSRWLockExclusive(&srw);
std::cout << "sleep종료" << std::endl;
ReleaseSRWLockExclusive(&srw);
AcquireSRWLockExclusive(&srw);
ReleaseSRWLockExclusive(&srw);
Sleep(INFINITE);
AcquireSRWLockExclusive(&srw);
for (std::thread& t : tv)
{
if (t.joinable())
t.join();
}
return 0;
}
값을 이리저리 바꾸고, 주석처리하면서 테스트했다.






또한 아무것도 없는 상태에서는 포인터값을 -1해주는 것을 확인했다.
#include <iostream>
#include <Windows.h>
#include <thread>
#include <vector>
SRWLOCK srw;
void ThreadFunc()
{
AcquireSRWLockExclusive(&srw);
std::cout << "t 실행" << std::endl;
ReleaseSRWLockExclusive(&srw);
}
int main()
{
InitializeSRWLock(&srw);
AcquireSRWLockExclusive(&srw);
ReleaseSRWLockExclusive(&srw);
ReleaseSRWLockExclusive(&srw);
ReleaseSRWLockExclusive(&srw);
ReleaseSRWLockExclusive(&srw);
ReleaseSRWLockExclusive(&srw); //
std::vector<std::thread> tv;
for (int i = 0; i < 1; i++)
{
tv.push_back(std::thread(ThreadFunc));
}
ReleaseSRWLockExclusive(&srw);
AcquireSRWLockExclusive(&srw);
std::cout << "메인 실행" << std::endl;
ReleaseSRWLockExclusive(&srw);
for (std::thread& t : tv)
{
if (t.joinable())
t.join();
}
return 0;
}
}
또한 Release를 여러번 하고 Acquire를 시도했을 때
0번 비트가 1이냐 0이냐에 따라 잘 실행되고, 실행되지 않고를 확인할 수 있었다. 처음 lock 획득을 0번째 비트로만 확인하기 때문에 그렇지 않다면 후에 작업하는 과정에서 에러를 뱉을 수 있지만, 값이 ffff'fff0같은 상황이라면 락을 획득할 수 있다고 판단한다.(좋은 것인가? 나쁜 것인가?)

처음 진입했다면 그대로 종료한다.
2.그렇지 않다면 진입 횟수를 증가시킨다.

( 0x00000011 -> 0x00000021 ),진입 횟수가 늘어날 수록 카운팅도 늘어남.
모든 반납이 완료되면 종료한다.

그렇지 않다면

shared 카운트 수를 줄인 후 리턴한다.
srw를 exclusive형태로 사용하는데 shared 로 락을 획득하려고 하면 ..
(또는 shared로 사용하고 있는데 exclusive 형태로 사용하려고 하면..) WaitOnAddress 방식을 통해 대기한다.
CRITICAL_SECTION과 SRW_LOCK은 락을 획득한 스레드가 아닌 다른 스레드가 락을 해제할 수도 있다는 점도 테스트를 하면서 확인했는데 상당히 놀라웠다..
전체적인 로직은 실력이 부족해서 파악할 수 없었지만 동작에 대해서 간단하게 훑어봤다는 점에 의의를 둬야할 것 같다. 나중에 기억 안 날 때 보기 위해서 만들었는데 그때는 이 글을 보고 잘 떠올렸으면 좋겠다.