SRWLock
读写锁在对资源进行保护的同时,还能区分想要读取资源值的线程(读取者线程)和想要更新资源的线程(写入者线程):
对于读取者线程,读写锁会允许他们并发的执行。
当有写入者线程在占有资源时,读写锁会让其它写入者线程和读取者线程等待。
对于一个读写锁,有两种获取方式:共享(Shared)或独占(Exclusive)。
如果当前读写锁处于空闲状态,那么当多个线程同时以共享方式访问该读写锁时,都可以成功;
而此时如果一个线程以独占的方式访问该读写锁,那么它会等待所有共享访问都结束后才可以成功。在读写锁被独占访问的过程中,再次共享和独占请求访问该锁,都会进行等待状态。
相关函数
//微软定义
typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
typedef struct _RTL_SRWLOCK {
PVOID Ptr;
} RTL_SRWLOCK, *PRTL_SRWLOCK;
// 初始化读写锁
WINBASEAPI
VOID
WINAPI
InitializeSRWLock(
__out PSRWLOCK SRWLock
);
// 独占式访问
WINBASEAPI
VOID
WINAPI
AcquireSRWLockExclusive(
__inout PSRWLOCK SRWLock
);
// 共享式访问
WINBASEAPI
VOID
WINAPI
AcquireSRWLockShared(
__inout PSRWLOCK SRWLock
);
// 独占式释放
WINBASEAPI
VOID
WINAPI
ReleaseSRWLockExclusive(
__inout PSRWLOCK SRWLock
);
// 共享式释放
WINBASEAPI
VOID
WINAPI
ReleaseSRWLockShared(
__inout PSRWLOCK SRWLock
);
代码举例
// SRWLock-ThreadSynchronization.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
using namespace std;
int __v1 = 10;
SRWLOCK __SRWLock;
DWORD WINAPI SharedReadThreadProcedure(LPVOID ParameterData);
DWORD WINAPI SharedWriteThreadProcedure(LPVOID ParameterData);
DWORD WINAPI ExclusiveReadThreadProcedure(LPVOID ParameterData);
DWORD WINAPI ExclusiveWriteThreadProcedure(LPVOID ParameterData);
int _tmain(int argc, _TCHAR* argv[])
{
InitializeSRWLock(&__SRWLock);
HANDLE ThreadHandle[4] = { NULL };
for (int i = 0; i < 2; i++)
{
//0,1
ThreadHandle[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SharedReadThreadProcedure, (LPVOID)(i+1),//1,2
0, NULL);
}
for (int i = 0; i < 2; i++)
{
//2,3
ThreadHandle[i+2] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SharedWriteThreadProcedure, (LPVOID)(i+3),//3,4
0, NULL);
}
for (int i = 0; i < 2; i++)
{
//4,5
ThreadHandle[i + 4] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ExclusiveReadThreadProcedure, (LPVOID)(i + 5),//5,6
0, NULL);
}
for (int i = 0; i < 2; i++)
{
//6,7
ThreadHandle[i + 6] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ExclusiveWriteThreadProcedure, (LPVOID)(i + 7),//7,8
0, NULL);
}
WaitForMultipleObjects(8, ThreadHandle, TRUE, INFINITE);
for (int i=0;i<8;i++)
{
if (ThreadHandle[i]!=NULL)
{
CloseHandle(ThreadHandle[i]);
ThreadHandle[i] = NULL;
}
}
printf("Input AnyKey To Exit\r\n");
getchar();
return 0;
}
DWORD WINAPI SharedReadThreadProcedure(LPVOID ParameterData)
{
DWORD ThreadID = (int)ParameterData;
AcquireSRWLockShared(&__SRWLock);
for (int i = 0; i < 100; i++)
{
printf("SharedReadThreadID:%d %d\r\n", ThreadID, __v1);
}
ReleaseSRWLockShared(&__SRWLock);
return 0;
}
DWORD WINAPI SharedWriteThreadProcedure(LPVOID ParameterData)
{
int i = 0;
DWORD ThreadID = (int)ParameterData;
AcquireSRWLockExclusive(&__SRWLock);
for (i = 0; i < 100; i++)
{
printf("SharedWriteThreadID:%d %d\r\n", ThreadID, __v1);
}
ReleaseSRWLockExclusive(&__SRWLock);
return 0;
}
DWORD WINAPI ExclusiveReadThreadProcedure(LPVOID ParameterData)
{
DWORD ThreadID = (int)ParameterData;
AcquireSRWLockShared(&__SRWLock);
for (int i = 0; i < 50; i++)
{
printf("ExclusiveReadThreadID:%d %d\r\n", ThreadID, __v1);
}
ReleaseSRWLockShared(&__SRWLock);
return 0;
}
DWORD WINAPI ExclusiveWriteThreadProcedure(LPVOID ParameterData)
{
int i = 0;
DWORD ThreadID = (int)ParameterData;
AcquireSRWLockExclusive(&__SRWLock);
for (i = 0; i < 50; i++)
{
printf("ExclusiveWriteThreadID:%d %d\r\n", ThreadID, __v1);
}
ReleaseSRWLockExclusive(&__SRWLock);
return 0;
}