Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
동기화에 대해서는 많은 분들이 고민을 많이 해보셨을 것이고 단순히Spinlock 을 사용해서 동기화를 구현한 분들도 계실 것입니다.
Spinlock 을 사용하면 어떤 문제가 있을까요? 한번에 하나의 Thread 만 접근이 가능하다는 것인데 다수의 Thread 가 공용 Buffer 를 Read 만 하는 것이라면 동시에 접근을 해도 문제가 없을 것입니다. Buffer 를 변경하는 경우에만 동시에 접근이 안되도록 하려면 어떻게 해야 할까요?
Executive Resource (ERESOURCE) 를 이용하여 동기화를 구현 하면 됩니다.
사용법은 다음과 같습니다.
// 선언
ERESOURCE rResourceLock;
// 초기화
ExInitializeResourceLite( &rResourceLock );
// 배타적 lock
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite( &rResourceLock, TRUE );
// 공유 lock
KeEnterCriticalRegion();
ExAcquireResourceSharedLite( &rResourceLock, TRUE );
// lock 해제
ExReleaseResourceLite( &rResourceLock );
KeLeaveCriticalRegion();
// 정리
ExDeleteResourceLite( &rResourceLock );
내부 동작이 어떻게 되는지 살펴 보았더니 다음과 같습니다.
Exclusive lock 이 어떤 Thread 에 의해 소유 되거나 요청되어 있는 상태에서 Share lock 요청이 호출되게 되면 내부적으로 semaphore 를 가지고 Exclusive lock 이 끝나기를 기다리게 됩니다.
Exclusive lock 을 호출했던 Thread 가 Release 를 호출하면 Semaphore 에서 대기하던 Thread 들이 깨어나서 작업을 하게 됩니다.
Share lock 을 가지고 있는 상태에서 Exclusive lock 요청이 호출되면 내부적으로 Event 를가지고 Share lock 들이 모두 끝나기를 기다리게 됩니다. 모든 Share lock 이 Release 되면 Event 를 대기하던 Thread 들이 깨어나게 됩니다.
내부적으로 Spinlock 을 사용해서 ERESOURCE 내부 Data 의 동기화를 보장 합니다.
감사합니다.