`

读写锁SRWLock

 
阅读更多

 

       读写锁在对资源进行保护的同时,还能区分想要读取资源值的线程(读取者线程)和想要更新资源的线程(写入者线程)。

       对于读取者线程,读写锁会允许他们并发的执行。当有写入者线程在占有资源时,读写锁会让其它写入者线程和读取者线程等待。

       因此用读写锁来解决读者写者问题会使代码非常清晰和简洁。

 

       SRWLock 允许我们区分那些想要读取资源的值的线程(读取者线程)和想要更新资源值的线程(写入者线程)

       所有的读取者线程在同一时刻访问共享资源是可以的,这是因为仅仅读取资源的值并不存在破坏数据的风险。

       只有当写入者线程想要对资源进行更新的时候才需要同步。

       在这种情况下,写入者线程应该独占对资源的访问权: 任何其他线程,无论是读取者线程还是写入者线程,都不允许访问资源。

 

相关函数介绍:

第一个 InitializeSRWLock

函数功能:初始化读写锁

函数原型:VOID InitializeSRWLock(PSRWLOCK SRWLock);

函数说明:初始化(没有删除或销毁SRWLOCK的函数,系统会自动清理) 

 

第二个 AcquireSRWLockExclusive

函数功能:写入者线程申请写资源。

函数原型:VOID AcquireSRWLockExclusive(PSRWLOCK SRWLock);

 

第三个 ReleaseSRWLockExclusive

函数功能:写入者线程写资源完毕,释放对资源的占用。

函数原型:VOID ReleaseSRWLockExclusive(PSRWLOCK SRWLock);

 

第四个 AcquireSRWLockShared

函数功能:读取者线程申请读资源。

函数原型:VOID AcquireSRWLockShared(PSRWLOCK SRWLock);

 

第五个 ReleaseSRWLockShared

函数功能:读取者线程结束读取资源,释放对资源的占用。

函数原型:VOID ReleaseSRWLockShared(PSRWLOCK SRWLock);

 

注意一个线程仅能锁定资源一次,不能多次锁定资源。

 

实例代码如下:

#include <iostream>
#include <windows.h>
#include <process.h>

using namespace std;

const int NUM = 30, READER_SIZE = 10;
HANDLE thread_r[NUM], thread_o[NUM], thread_w[NUM];
CRITICAL_SECTION sc, oc;
SRWLOCK rwLock;

unsigned int __stdcall read(PVOID pm) {
	AcquireSRWLockShared(&rwLock);	
	EnterCriticalSection(&sc);
	cout << GetCurrentThreadId() << "号,读进程开始..." << endl;
	LeaveCriticalSection(&sc);

	Sleep(rand() % 100);

	EnterCriticalSection(&sc);
	cout << GetCurrentThreadId() << "号,读进程结束..." << endl;
	LeaveCriticalSection(&sc);
	ReleaseSRWLockShared(&rwLock);
	return 0;
}

unsigned int __stdcall write(PVOID pm) {
	AcquireSRWLockExclusive(&rwLock);
	cout << GetCurrentThreadId() << "号,--------------写进程开始..." << endl;
	Sleep(rand() % 100);
	cout << GetCurrentThreadId() << "号,--------------写进程执行完毕..." << endl;
	ReleaseSRWLockExclusive(&rwLock);
	return 0;
}

int main() {
	InitializeCriticalSection(&sc);
	InitializeCriticalSection(&oc);
	InitializeSRWLock(&rwLock);

	int i = 0;
	for(; i<NUM; i++) {
		thread_r[i] = (HANDLE) _beginthreadex(NULL, 0, read, NULL, 0, NULL);
		thread_w[i] = (HANDLE) _beginthreadex(NULL, 0, write, NULL, 0, NULL);
	}
	
	WaitForMultipleObjects(NUM, thread_r, TRUE, INFINITE);
//	Sleep(100);
	// 在执行30个 读线程
	for(i=0; i<NUM; i++) {
		thread_o[i] = (HANDLE) _beginthreadex(NULL, 0, read, NULL, 0, NULL);
	}
//	writeLock = true;
	WaitForMultipleObjects(NUM, thread_w, TRUE, INFINITE);
	WaitForMultipleObjects(NUM, thread_o, TRUE, INFINITE);

	DeleteCriticalSection(&sc);
	DeleteCriticalSection(&oc);

	cout << "运行完毕" << endl;
	getchar();
	return 0;
}

运行效果如下:







总结一下读写锁SRWLock

1.读写锁声明后要初始化,但不用销毁,系统会自动清理读写锁。

2.读取者和写入者分别调用不同的申请函数和释放函数。

 

  • 大小: 47.3 KB
  • 大小: 31.6 KB
  • 大小: 27.1 KB
  • 大小: 27.4 KB
  • 大小: 6.6 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics