Chinaunix首页 | 论坛 | 博客
  • 博客访问: 905540
  • 博文数量: 201
  • 博客积分: 8078
  • 博客等级: 中将
  • 技术积分: 2162
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-20 17:22
文章分类

全部博文(201)

文章存档

2013年(3)

2012年(11)

2011年(34)

2010年(25)

2009年(51)

2008年(77)

分类: WINDOWS

2010-10-24 18:12:16

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

#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;
}


阅读(2307) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~