Chinaunix首页 | 论坛 | 博客
  • 博客访问: 613034
  • 博文数量: 152
  • 博客积分: 2684
  • 博客等级: 少校
  • 技术积分: 1126
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-29 11:03
文章分类
文章存档

2012年(6)

2011年(96)

2010年(50)

分类: WINDOWS

2010-10-29 15:09:58

说是简单是因为代码很短,并且很容易看懂,也很容易修改。

#include <stdio.h>
#include <assert.h>
#include <windows.h>

#define LOCK_READ 0
#define LOCK_WRITE 1

class rwlock{
    public:
        rwlock();
        ~rwlock();

    public:
        void lock(int direct);
        void unlock(int direct);

        void lock_exclusive(void);
        void unlock_exclusive(void);

        void wrlock() { lock(LOCK_WRITE); }
        void wrunlock() { unlock(LOCK_WRITE); }

        void rdlock() { lock(LOCK_READ); }
        void rdunlock() { unlock(LOCK_READ); }

    private:
        volatile LONG count;
        volatile LONG direct;
        HANDLE finish_event;
        CRITICAL_SECTION start_lock;
};

rwlock::rwlock()
{
    count = 0;
    direct = 0;
    finish_event = CreateEvent(NULL, FALSE, FALSE, NULL);
    InitializeCriticalSection(&start_lock);
}

rwlock::~rwlock()
{
    assert(count == 0);
    CloseHandle(finish_event);
    DeleteCriticalSection(&start_lock);
}

void rwlock::lock(int _direct)
{
    EnterCriticalSection(&start_lock);
    while (count > 0 &&
            direct != _direct) {
        WaitForSingleObject(finish_event, INFINITE);
    }
    direct = _direct;
    InterlockedIncrement(&count);
    LeaveCriticalSection(&start_lock);
}

void rwlock::unlock(int _direct)
{
    assert(count > 0);
    assert(direct == _direct);
    InterlockedDecrement(&count);
    SetEvent(finish_event);
}

void rwlock::lock_exclusive(void)
{
    EnterCriticalSection(&start_lock);
    while (count > 0 &&
            direct != _direct) {
        WaitForSingleObject(finish_event, INFINITE);
    }
    InterlockedIncrement(&count);
}

void unlock_exclusive(void)
{
    InterlockedDecrement(&count);
    LeaveCriticalSection(&start_lock);
}

static DWORD CALLBACK ReadFunc(LPVOID lpVoid)
{
    rwlock * plock = (rwlock *)lpVoid;
    while ( 1 ) {
        plock->rdlock();
        printf("Start Read: threaid %x\n", GetCurrentThreadId());
        printf("Call Read: threaid %x\n", GetCurrentThreadId());
        printf("End Read: threaid %x\n", GetCurrentThreadId());
        plock->rdunlock();
    }
    return 0;
}

int main(int argc, char * argv[])
{
    DWORD id;
    rwlock lock;

    for (int i = 0; i < 10; i ++) {
        HANDLE handle = CreateThread(NULL, 0, ReadFunc, &lock, 0, &id);
        CloseHandle(handle);
    }

    while ( 1 ) {
        lock.wrlock();
        printf("Start Write: threaid %x\n", GetCurrentThreadId());
        for (int j = 0; j < 10; j++) {
            printf("Call Write: threaid %x\n", GetCurrentThreadId());
        }
        printf("End Write: threaid %x\n", GetCurrentThreadId());
        lock.wrunlock();
    }

    return 0;
}


本博文转载于:起风啦 的博客
阅读(1295) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~