您的位置:首页 > 其它

多线程例子—读者,作家使用读写锁(SRWLOCK)

2014-08-20 13:30 232 查看
读写锁在对资源进行保护的同时,还能区分想要读取资源值的线程(读取者线程)和想要更新资源的线程(写入者线程)。

对于读取者线程,读写锁会允许他们并发的执行。因此不用变量记录读者的个数,手动在第一个读者阅读时占用资源,在最后一个读者时释放资源,读写锁帮忙完成以上工作

当有写入者线程在占有资源时,读写锁会让其它写入者线程和读取者线程等待。

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

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



//读写锁SRWLock
#include <stdio.h>
#include <process.h>
#include <windows.h>

const int READER_NUM = 5;  //读者个数
//关键段和事件
CRITICAL_SECTION g_cs;
SRWLOCK          g_srwLock; 

//读者线程输出函数(变参函数的实现)
void ReaderPrintf(char *pszFormat, ...)
{
	va_list   pArgList;
	va_start(pArgList, pszFormat);
	EnterCriticalSection(&g_cs);
	vfprintf(stdout, pszFormat, pArgList);
	LeaveCriticalSection(&g_cs);
	va_end(pArgList);
}

//写者线程输出函数
void WriterPrintf(char *pszStr)
{
	EnterCriticalSection(&g_cs);
	printf("     %s\n", pszStr);
	LeaveCriticalSection(&g_cs);
}
//读者线程函数
unsigned int __stdcall ReaderThreadFun(PVOID pM)
{
	ReaderPrintf("     编号为%d的读者进入等待中...\n", GetCurrentThreadId());
	//读者申请读取文件
	AcquireSRWLockShared(&g_srwLock); //<读取者线程申请读资源。

	//读取文件
	ReaderPrintf("编号为%d的读者开始读取文件...\n", GetCurrentThreadId());
	Sleep(rand() % 100);
	ReaderPrintf(" 编号为%d的读者结束读取文件\n", GetCurrentThreadId());

	//读者结束读取文件
	ReleaseSRWLockShared(&g_srwLock); //<读取者线程结束读取资源,释放对资源的占用。
	return 0;
}

//写者线程函数
unsigned int __stdcall WriterThreadFun(PVOID pM)
{
	WriterPrintf("写者线程进入等待中...");
	//写者申请写文件
	AcquireSRWLockExclusive(&g_srwLock);  //<写入者线程申请写资源。

	//写文件
	WriterPrintf("  写者开始写文件.....");
	Sleep(rand() % 100);
	WriterPrintf("  写者结束写文件");

	//标记写者结束写文件
	ReleaseSRWLockExclusive(&g_srwLock); //<写入者线程写资源完毕,释放对资源的占用。
	return 0;
}
int main()
{
	//初始化读写锁和关键段
	InitializeCriticalSection(&g_cs);
	InitializeSRWLock(&g_srwLock);  //<初始化(没有删除或销毁SRWLOCK的函数,系统会自动清理)

	HANDLE hThread[READER_NUM + 1];
	int i;
	//先启动二个读者线程
	for (i = 1; i <= 2; i++)
		hThread[i] = (HANDLE)_beginthreadex(NULL, 0, ReaderThreadFun, NULL, 0, NULL);
	//启动写者线程
	hThread[0] = (HANDLE)_beginthreadex(NULL, 0, WriterThreadFun, NULL, 0, NULL);
	Sleep(50);
	//最后启动其它读者结程
	for ( ; i <= READER_NUM; i++)
		hThread[i] = (HANDLE)_beginthreadex(NULL, 0, ReaderThreadFun, NULL, 0, NULL);
	WaitForMultipleObjects(READER_NUM + 1, hThread, TRUE, INFINITE);
	for (i = 0; i < READER_NUM + 1; i++)
		CloseHandle(hThread[i]);

	//销毁关键段
	DeleteCriticalSection(&g_cs);
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: