linux内存锁页,Linux Windows 通用的内存读写锁。

读可以并发,写是互斥,读写互斥,读写按顺序操作。

Linux上有现成的,但是Windows上貌似没有这样的机制,没办法,自己实现一个。好恶心啊,放在这里,以备后用。

pthread_rwlock.h

#ifndef PTHREAD_RWLOCK_H

#define PTHREAD_RWLOCK_H

#ifdef WIN32

#include "StdAfx.h"

typedef enum

{

RW_READ_LOCK = 0,

RW_WRITE_LOCK

}pthread_rwlock_t_lock_mode;

typedef struct pthread_rwlock_t_node

{

HANDLE hEvent;

pthread_rwlock_t_lock_mode eLockMode;

struct pthread_rwlock_t_node *pNext;

}pthread_rwlock_t_node;

typedef struct pthread_rwlock_t

{

HANDLE hMutex;

pthread_rwlock_t_node *pFirstNode;

}pthread_rwlock_t;

typedef void pthread_rwlockattr_t;

extern int pthread_rwlock_destroy(pthread_rwlock_t *

rwlock);

extern int pthread_rwlock_init(pthread_rwlock_t * rwlock,

const pthread_rwlockattr_t *attr);

extern int pthread_rwlock_rdlock(pthread_rwlock_t *

rwlock);

extern int pthread_rwlock_unlock(pthread_rwlock_t *

rwlock);

extern int pthread_rwlock_wrlock(pthread_rwlock_t *

rwlock);

typedef pthread_rwlock_t RWLockT;

#define RWInitLock(_lockdata_)

(pthread_rwlock_init((_lockdata_), NULL) == 0)

#define RWReadLock(_lockdata_)

(pthread_rwlock_rdlock(_lockdata_) == 0)

#define RWWriteLock(_lockdata_)

(pthread_rwlock_wrlock(_lockdata_) == 0)

#define RWUnlock(_lockdata_)

(pthread_rwlock_unlock(_lockdata_) == 0)

#define RWCloseLock(_lockdata_)

(pthread_rwlock_destroy(_lockdata_) == 0)

#endif

#endif

pthread_rwlock.cpp

#include "StdAfx.h"

#include "pthread_rwlock.h"

#define Assert ASSERT

#ifdef WIN32

int pthread_rwlock_destroy (pthread_rwlock_t *

rwlock)

{

Assert(NULL != rwlock);

if (WAIT_OBJECT_0 !=

WaitForSingleObject(rwlock->hMutex,

INFINITE))

{

return -1;

}

if (NULL != rwlock->pFirstNode)

{

pthread_rwlock_t_node *pLast;

pthread_rwlock_t_node *p;

pLast = rwlock->pFirstNode;

while(NULL != pLast)

{

CloseHandle(pLast->hEvent);

p = pLast->pNext;

free(pLast);

pLast = p;

}

}

CloseHandle(rwlock->hMutex);

return 0;

}

int pthread_rwlock_init (pthread_rwlock_t * rwlock, const

pthread_rwlockattr_t *attr)

{

Assert(NULL != rwlock);

Assert(NULL == attr);

rwlock->pFirstNode = NULL;

rwlock->hMutex = CreateMutex(NULL, false,

NULL);

if (INVALID_HANDLE_VALUE ==

rwlock->hMutex)

return -1;

return 0;

}

int pthread_rwlock_rdlock(pthread_rwlock_t *

rwlock)

{

pthread_rwlock_t_node *p;

pthread_rwlock_t_node *pNew;

bool bCanRunNow = true;

Assert(NULL != rwlock);

if (WAIT_OBJECT_0 !=

WaitForSingleObject(rwlock->hMutex,

INFINITE))

return -1;

pNew =

(pthread_rwlock_t_node*)malloc(sizeof(pthread_rwlock_t_node));

if (NULL == pNew)

{

fprintf(stderr, ("Out of memory\n"));

ReleaseMutex(rwlock->hMutex);

return -1;

}

pNew->eLockMode = RW_READ_LOCK;

pNew->hEvent = CreateEvent(NULL, true, false,

NULL);

pNew->pNext = NULL;

if (INVALID_HANDLE_VALUE == pNew->hEvent)

{

ReleaseMutex(rwlock->hMutex);

free(pNew);

return -1;

}

if (NULL == rwlock->pFirstNode)

{

rwlock->pFirstNode = pNew;

}

else

{

p = rwlock->pFirstNode;

while (NULL != p->pNext)

{

if (RW_READ_LOCK != p->eLockMode)

bCanRunNow = false;

p = p->pNext;

}

if (RW_READ_LOCK != p->eLockMode)

bCanRunNow = false;

p->pNext = pNew;

}

if (bCanRunNow)

SetEvent(pNew->hEvent);

ReleaseMutex(rwlock->hMutex);

if (WAIT_OBJECT_0 !=

WaitForSingleObject(pNew->hEvent,

INFINITE))

return -1;

return 0;

}

int pthread_rwlock_unlock(pthread_rwlock_t *

rwlock)

{

pthread_rwlock_t_node *p;

Assert(NULL != rwlock);

if (WAIT_OBJECT_0 !=

WaitForSingleObject(rwlock->hMutex,

INFINITE))

return -1;

if (NULL == rwlock->pFirstNode)

{

ReleaseMutex(rwlock->hMutex);

return 0;

}

p = rwlock->pFirstNode;

rwlock->pFirstNode =

p->pNext;

CloseHandle(p->hEvent);

free(p);

if (NULL != rwlock->pFirstNode)

{

if (RW_READ_LOCK ==

rwlock->pFirstNode->eLockMode)

{

p = rwlock->pFirstNode;

while(NULL != p && RW_READ_LOCK ==

p->eLockMode)

{

SetEvent(p->hEvent);

p = p->pNext;

}

}

else

{

SetEvent(rwlock->pFirstNode->hEvent);

}

}

ReleaseMutex(rwlock->hMutex);

return 0;

}

int pthread_rwlock_wrlock(pthread_rwlock_t *

rwlock)

{

pthread_rwlock_t_node *p;

pthread_rwlock_t_node *pNew;

bool bCanRunNow = false;

Assert(NULL != rwlock);

if (WAIT_OBJECT_0 !=

WaitForSingleObject(rwlock->hMutex,

INFINITE))

return -1;

pNew =

(pthread_rwlock_t_node*)malloc(sizeof(pthread_rwlock_t_node));

if (NULL == pNew)

{

fprintf(stderr, "Out of memory\n");

ReleaseMutex(rwlock->hMutex);

return -1;

}

pNew->eLockMode = RW_WRITE_LOCK;

pNew->hEvent = CreateEvent(NULL, true, false,

NULL);

pNew->pNext = NULL;

if (INVALID_HANDLE_VALUE == pNew->hEvent)

{

ReleaseMutex(rwlock->hMutex);

free(pNew);

return -1;

}

if (NULL == rwlock->pFirstNode)

{

rwlock->pFirstNode = pNew;

bCanRunNow = true;

}

else

{

p = rwlock->pFirstNode;

while (NULL != p->pNext)

{

p = p->pNext;

}

p->pNext = pNew;

}

if (bCanRunNow)

SetEvent(pNew->hEvent);

ReleaseMutex(rwlock->hMutex);

if (WAIT_OBJECT_0 !=

WaitForSingleObject(pNew->hEvent,

INFINITE))

return -1;

return 0;

}

#endif

使用方法:

// pthread_rwlock_test.cpp : Defines the entry point for

the console application.

//

#include "stdafx.h"

#include "pthread_rwlock_test.h"

#include "pthread_rwlock.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/

// The one and only application object

CWinApp theApp;

using namespace std;

RWLockT lockdata;

HANDLE hMutex;

int counter = 1;

#define Log0(X) do{ LockMutex(hMutex); cout

<< (X)

<< endl; UnlockMutex(hMutex); }

while(0)

#define Log1(X, Y) do{ LockMutex(hMutex); cout

<< X <<

Y << endl; UnlockMutex(hMutex); }

while(0)

bool

LockMutex(HANDLE hMutex)

{

if (WAIT_OBJECT_0 != WaitForSingleObject(hMutex,

INFINITE))

return false;

return true;

}

bool UnlockMutex(HANDLE

hMutex)

{

return ReleaseMutex(hMutex);

}

DWORD WINAPI ThreadFunc(

LPVOID lpParam )

{  pthread_rwlock_t_lock_mode mod =

(pthread_rwlock_t_lock_mode)(int)lpParam;

if (mod == RW_READ_LOCK)

{

if

(!RWReadLock(&lockdata))

Log1( "Read

Error", GetLastError());

counter ++;

Sleep(1000);

Log1("read", counter);

}

else

{

if

(!RWWriteLock(&lockdata))

Log1( "Write

Error", GetLastError());

counter--;

Sleep(1000);

Log1("write", counter);

}

if

(counter < 0)

DebugBreak();

mod ==

RW_READ_LOCK ? --counter : ++ counter;

RWUnlock(&lockdata);

return

0;

}

int _tmain(int argc,

TCHAR* argv[], TCHAR* envp[])

{

int nRetCode = 0;

//

initialize MFC and print and error on failure

if (!AfxWinInit(::GetModuleHandle(NULL), NULL,

::GetCommandLine(), 0))

{

// TODO: change error code to

suit your needs

cerr

<< _T("Fatal Error: MFC

initialization failed") <<

endl;

nRetCode = 1;

}

else

{

hMutex = CreateMutex(NULL,

FALSE, NULL);

if

(!RWInitLock(&lockdata))

{

Log1("Init

error" , GetLastError());

return

0;

}

CreateThread(NULL, 0,

ThreadFunc, (LPVOID)RW_WRITE_LOCK, 0, NULL);

Sleep(100);

CreateThread(NULL, 0,

ThreadFunc, (LPVOID)RW_READ_LOCK, 0, NULL);

CreateThread(NULL, 0,

ThreadFunc, (LPVOID)RW_READ_LOCK, 0, NULL);

CreateThread(NULL, 0,

ThreadFunc, (LPVOID)RW_READ_LOCK, 0, NULL);

CreateThread(NULL, 0,

ThreadFunc, (LPVOID)RW_READ_LOCK, 0, NULL);

Sleep(100);

CreateThread(NULL, 0,

ThreadFunc, (LPVOID)RW_WRITE_LOCK, 0, NULL);

CreateThread(NULL, 0,

ThreadFunc, (LPVOID)RW_WRITE_LOCK, 0, NULL);

CreateThread(NULL, 0,

ThreadFunc, (LPVOID)RW_WRITE_LOCK, 0, NULL);

CreateThread(NULL, 0,

ThreadFunc, (LPVOID)RW_WRITE_LOCK, 0, NULL);

Sleep(100);

CreateThread(NULL,

0, ThreadFunc, (LPVOID)RW_READ_LOCK, 0, NULL);

CreateThread(NULL, 0,

ThreadFunc, (LPVOID)RW_READ_LOCK, 0, NULL);

CreateThread(NULL, 0,

ThreadFunc, (LPVOID)RW_READ_LOCK, 0, NULL);

CreateThread(NULL, 0,

ThreadFunc, (LPVOID)RW_READ_LOCK, 0, NULL);

CreateThread(NULL, 0,

ThreadFunc, (LPVOID)RW_READ_LOCK, 0, NULL);

CreateThread(NULL, 0,

ThreadFunc, (LPVOID)RW_READ_LOCK, 0, NULL);

Sleep(100);

CreateThread(NULL,

0, ThreadFunc, (LPVOID)RW_WRITE_LOCK, 0, NULL);

Sleep(100);

CreateThread(NULL,

0, ThreadFunc, (LPVOID)RW_READ_LOCK, 0, NULL);

Sleep(20000);

RWCloseLock(&lockdata);

}

return nRetCode;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值