Slim读/写锁(SRWLock)及同步方式比较
来源:互联网 发布:淘宝人像摄影 编辑:程序博客网 时间:2024/06/05 11:18
一、SRWLock锁的工作原理
SRWLock锁的目的和关键段相同:对一个资源进行保护,不让其他线程访问它。但是,与关键段不同的是:SRWLock锁允许我们区分哪些想要读取资源的值的线程(读取者线程)和想要更新资源的值的线程(写入者线程)。让所有的读取者线程在同一时刻访问共享资源应该是可行的,这是因为读取资源并不存在破坏资源的风险。只有当写入者线程想要对资源进行更新的时候才需要进行同步。在这种情况下:写入者线程独占对资源的访问权。
二、SRWLock锁的用法
首先,需要分配一个SRWLOCK结构并进行初始化:
- VOID WINAPI InitializeSRWLock(
- _Out_ PSRWLOCK SRWLock
- );
对于SRWLOCK结构的具体内容,我们没有必要去详细了解。
写入者进程的操作
一旦SRWLock的初始化完成之后,写入者线程就可以调用AcquireSRWLockExclusive,将SRWLOCK对象的地址作为参数传入,以尝试获得对被保护资源的独占访问权。
- VOID WINAPI AcquireSRWLockExclusive(
- _Inout_ PSRWLOCK SRWLock
- );
在完成对资源的更新之后。应该调用ReleaseSRWLockExclusive函数,并将SRWLOCK对象的地址作为参数传入,解除对资源的锁定。
- VOID WINAPI ReleaseSRWLockExclusive(
- _Inout_ PSRWLOCK SRWLock
- );
读取者的操作
读取者调用的两个参数是:
- VOID AcquireSRWLockShared(PSRWLOCK SRWLock);
- VOID ReleaseSRWLockShared(PSRWLOCK SRWLock);
不存在删除或销毁SRWLock的函数,系统会自动执行清理工作。
与关键段相比,SRWLock缺乏下面两个特性:
(1)不存在TryEnter(Shared/Exclusive)SRWLock之类的函数。如果锁已经被占用,那么调用AcquireSRWLock(SHared/Exclusive)会阻塞调用线程。
(2)不能递归调用SRWLOCK。一个线程不能为了多次写入资源而多次锁定资源,然后多次调用ReleaseSRWLock来释放对资源的锁定。
但是,如果可以接受这些限制,就可以用SRWLock来代替关键段,并获得实际性能和可伸缩性的提升。
三、同步机制性能的比较
通过一个简单的基准测试可以比较各种同步机制的性能:产生1、2和4个线程,使用不同的同步机制重复执行相同的任务,在双处理器上运行,得出的结果是:
用户模式下同步机制性能的对比实验结果如下(计数单位:微秒)
线程数
Volatile Read
Volatile Write
Interlocked Increment
Critical Section
SRWLock Shared
SRWLock Exclusive
Mutex
1
8
8
35
66
66
67
1060
2
8
76
153
268
134
148
11082
4
9
145
361
768
244
307
23785
各种机制对比:
(1)读取volatile长整型值,读取非常快,因为不需要进行任何同步,与CPU的高速缓存完全无关。
(2)写入volatile长整型值。单线程的时间和读取差不多,但是双线程的时候时间不只是加倍,这是因为CPU之间必须相互通信以维护高速缓存的一致性。如果机器有更多的CPU,那么性能还会下降,因为需要在更多的CPU之间进行通信来使得所有CPU的高速缓存一致。
(3)使用InterlockedIncrement来安全递增一个volatile长整型值。
它比第一种方法要慢,这是因为CPU必须锁定内存。使用两个线程要比一个线程慢得多,这是因为必须在两个CPU之间来回传输数据以维护高速缓存的一致性。
(4)使用关键段来读取一个volatile长整型值。
关键段比较慢,是因为我们必须先进入再离开。进入和离开需要修改CRITICAL_SECTION结果中的多个字段。4个线程需要花费更多时间,是因为上下文切换增大了发生争夺现象的可能性。
(5)使用SRWLock来读取一个volatile长整型值。
当有多个线程的时候,读操作比写操作快。由于多个线程会不断地写入锁的字段以及它保护的数据,因此各CPU必须在它们的高速缓存之间来回传输数据。
它的性能和关键段差不多,但是很多时候要优于关键段。建议的做法是用SRWLock替代关键段。
(6)使用同步内核对象互斥量。
互斥量是目前性能最差的,是因为等待互斥量以及后来释放互斥量需要线程每次在用户模式和内核模式之间却换,开销很大。
总结:应该首先尝试不要共享数据,然后依次使用volatile读取、volatile写入、Interlocked函数、SRWLock以及关键段。仅当这些都不能满足要求的时候,再使用内核对象。
实例代码:
#include <windows.h>
#include <windowsx.h>
#include <process.h>
#include <iostream>
using namespace std;
DWORD WINAPI FirstThread(PVOID pvParam);
DWORD WINAPI SecondThread(PVOID pvParam);
const long Count = 10000;
long g_nSum = 0;
SRWLOCK g_SRWLock; //定义SRWLOCK结构
int main()
{
InitializeSRWLock(&g_SRWLock) ;
HANDLE hThread1 = CreateThread(NULL,0,FirstThread,NULL,0,0);
HANDLE hThread2 = CreateThread(NULL,0,SecondThread,NULL,0,0);
CloseHandle(hThread1);
CloseHandle(hThread2);
Sleep(5000);
return 0;
}
DWORD WINAPI FirstThread(PVOID pvParam)
{
//执行写操作
AcquireSRWLockExclusive(&g_SRWLock);
cout << "Thread1 get the SRWLock , and do writing" << endl;
g_nSum = 0;
for(int i = 0;i<1000;++i)
{
g_nSum = 0;
for(int n=1; n<=Count; ++n)
{
g_nSum += n;
}
}
ReleaseSRWLockExclusive(&g_SRWLock);
return 0;
}
DWORD WINAPI SecondThread(PVOID pvParam)
{
//执行读操作
AcquireSRWLockShared(&g_SRWLock);
cout << "Thread1 get the SRWLock , and do reading" << endl;
cout << "g_num = " << g_nSum << endl;
ReleaseSRWLockShared(&g_SRWLock);
return 0;
}
- Slim读/写锁(SRWLock)及同步方式比较
- slim读/写锁 srwlock
- Windows线程同步之Slim读写锁(SRWLock)
- Windows线程同步之Slim读写锁(SRWLock)
- 线程同步之Slim读/写锁
- 线程同步 Slim读写锁 SRWLOCK 用户模式同步对象 InitializeSRWLock
- Slim读/写锁
- 多线程 -- Slim 读/写锁
- 用户模式下的线程同步——Slim读/写锁
- 线程同步三:Slim锁
- 写优先读写锁,读效率比 WINDOWS 的 SRWLOCK 慢一倍左右,百万级读锁要156ms
- 12.[个人]C++线程入门到进阶(12)----读者写者问题&读写锁SRWLock
- 多线程13: 读者写者问题继 读写锁SRWLock
- 同步方式比较
- 读写锁SRWLock
- 读写锁SRWLock
- SRWLock
- Windows核心编程笔记(八)用户模式下的线程同步 SRWLock剖析
- iOS-NSString
- WCSession
- 【spoj375】树链剖分 裸题
- DeepID3:Face Recognition with Very Deep Neural Networks
- java8 write file 写文件
- Slim读/写锁(SRWLock)及同步方式比较
- hdu1598 find the most comfortable road(并查集)
- 解决easuyi的linkbutton在按钮失效时,还会触发jquery的click事件的问题。
- mysql 安装后不能使用cmd进行访问
- 常用的MyEclipse快捷键(方便快捷)
- Android 内存泄漏分析利器——leakcanary
- vs2010编译运行出现LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏的解决办法
- 实现View上添加标签
- 4维数据显示 4 Dimensional visualization