본문 바로가기

프로그래밍/API

Windows에서 rwlock의 구현..

가끔씩 동기화 처리를 위해 rwlock(read/write)이 필요할때가 있다. 나도 이러한 구현 소스를 찾아 보기 위해
인터넷을 돌아 다니다 GDK관련 사이트에서 구현 소스를 얻은 것으로 기억한다.

rwlock의 최대 장점은 read는 중복해서 lock이 설정될수 있지만, write락은 CRITICAL_SECTION 처럼 단
 하나의 lock만 처리해 효율을 높이는데 사용될수 있다.

그럼 구현에 필요한 기본 자료형 부터 확인해보면..

typedef struct {
 HANDLE write_mutex;
 HANDLE read_event;
 LONG   readers;
} rwlock_t;


이 필요하고, 구조를 초기화 하기 위해서는

rwlock->readers = 0;
rwlock->read_event = CreateEvent(NULL, TRUE, FALSE, NULL);
rwlock->write_mutex = CreateMutex(NULL, FALSE, NULL);


이 필요하게 된다,

그럼 우선 read lock을 구현하기 위한 함수를 보면

int rwlock_rdlock( rwlock_t *rwlock, DWORD milliseconds)
{
    DWORD code = WaitForSingleObject( rwlock->write_mutex, milliseconds);

    switch (code)
    {
       case WAIT_TIMEOUT: return 0;
       default          : InterlockedIncrement(&rwlock->readers);
          if (!ResetEvent( rwlock->read_event) || !ReleaseMutex( rwlock->write_mutex))
       case WAIT_FAILED : return -1;
    } return 1;
}

이 되고, write lock은 read lock과 틀리게 read lock이 해제될때 까지 기다리도록 처리 해야 한다.

int rwlock_wrlock( rwlock_t *rwlock, DWORD milliseconds)
{
    DWORD code = WaitForSingleObject( rwlock->write_mutex, milliseconds);

    switch (code)
    {
       case WAIT_TIMEOUT: return 0;
       default          :
          if (rwlock->readers) {
             code = milliseconds
                    ? WaitForSingleObject( rwlock->read_event, milliseconds)
                    : WAIT_TIMEOUT;        
             if ((code == WAIT_FAILED) || (code == WAIT_TIMEOUT)) {
                /* Unable to wait for readers to finish, release write lock: */
               if (!ReleaseMutex( rwlock->write_mutex))
      case WAIT_FAILED: return -1;
               else {
                    ;
               } return ((code == WAIT_TIMEOUT) ? 0: -1);          
             }
         }
    } return 1;
}

이로서 필요에 따라, read 또는 write lock을 사용할수 있는 함수가 만들어 졌다.
다 같이 사용해 보아요~ ^^;