Slim读写锁
概述
- 目的和关键段一样,对一个资源进行保护,不让其他线程访问它。
- 和关键段不同的是,SRWLock允许我们区分那些想要读取资源的值的线程(读取者线程)以及想要更新资源的值的线程(写入者线程)
关于读写锁的功能
- 让所有的读取者线程同一时刻访问共享资源应该是可行的,因为仅仅读取资源的值并不存在破坏资源的风险。
- 只有当写入者线程想要对资源进行更新时才需要同步。
因为在这种情况下,写入者线程应该独占对资源的访问权:也就是任何其他线程,无论是读取者线程还是写入者线程,都不允许访问资源。
写入者线程
- 分配一个SRWLOCK结构并用InitializeSRWLock对它进行初始化
1 |
VOID InitializeSRWLock(PSRWLOCK SRWLock); |
- 一旦SRWLock的初始化完成之后,写入者线程就可以调用AcquireSRWLockExclusive这个函数,将SRWLOCK结构的地址作为参数传过去,以尝试获取对被保护的资源的独占访问权。
1 |
VOID AcquireSRWLockExclusive(PSRWLOCK SRWLock); |
- 完成对资源的更新以后,应该调用ReleaseSRWLockExclusive,并将SRWLOCK对象的地址作为参数传入,就可以接触对资源的锁定。
1 |
VOID ReleaseSRWLockExclusive(PSRWLOCK SRWLock); |
- 不存在用来删除或销毁SRWLOCK的函数,因为系统会自己执行清理工作。
读取者线程
- 对应的函数如下
1 2 |
VOID AcquireSRWLockShared(PSRWLock SRWLock); VOID ReleaseSRWLockShared(PSRWLock SRWLock); |
性能
- SRWLock的性能和关键段的性能差不多。
条件变量
概述
- 当想让写入者线程和读取者线程以独占模式或共享模式访问同一个资源的时候,我们可以使用SRWLock。
- 在这些情况下,如果读取者线程没有数据可读取,那么它应该将锁释放并等待,知道写入者线程产生了新的数据为止。
- 如果用来接收写入者线程产生的数据结构已满,那么写入者线程通过应该释放SRWLock锁并进入睡眠状态,直到读取者线程把数据结构清空为止。
- 如果让线程以原子方式把锁释放并将自己阻塞,直到某一条件已经达成为止。Windows通过SleepConditionVariableCS或SleepConditionVariableSRW函数,提供了一种条件变量,来达成这种工作。
- pConditionVariable指向一个已初始化的条件变量,调用线程正在等待该条件变量。
- 第二个参数是一个指向关键段或者SRWLock的指针,用来同步对共享资源的访问。
- dwMilliseconds表示希望线程花多少时间等待条件变量触发。
- Flags用来指定一旦条件变量被触发,我们希望以何种方式得到锁:
- 对于写入者线程来说,应该传入0,表示希望独占对资源的访问
- 对于读取者线程来说,应该传入CONDITION_VARIABLE_LOCKMODE_SHARD,表示希望共享对资源的访问。
- 当指定的时间用完的时候,如果条件变量未被触发,函数返回FALSE,否则函数返回TRUE。
当函数返回FALSE的时候,线程显然并没有获得锁或关键段。
1 2 3 4 5 6 7 8 |
BOOL SleepConditionVariableCS(PCONDITION_VARIABLE pConditionVariable, PCRITICAL_SECTION pCriticalSection, DWORD dwMilliseconds); BOOL SleepConditionVariableSRW(PCONDITION_VARIABLE pConditionVariable, PSRWLOCK pSRWLock, DWORD dwMilliseconds, ULONG Flags); |
- 当一个线程检测到相应的条件已经满足的时候,会调用WakeConditionVariable或者WakeAllConditionVariable,这样阻塞在Sleep*函数中的线程就会被唤醒。
- WakeConditionVariable会使一个在Sleep*函数中等待同一条件变量被触发的线程得到锁并返回,当这个线程释放同一个锁的时候,不会唤醒其他正在等待同一条件变量的线程。
- WakeAllConditionVariable会使一个或几个在Sleep*函数中等待这个条件变量被触发的线程得到对资源的访问权并返回。
如果要同一时刻允许多个写入者线程得到锁,可以传CONDITION_VARIABLE_LOCKMODE_SHARD。
1 2 3 |
VOID WakeConditionVariable(PCONDITION_VARIABLE ConditionVariable); VOID WakeAllConditionVariable(PCONDITION_VARIABLE ConditionVariable); |
本文为原创文章,版权归Aet所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ Soui二05/18
- ♥ breakpad记述:Windows07/27
- ♥ 关于异常的捕获和dump文件的生成07/05
- ♥ Windows 核心编程 _ 线程调度07/07
- ♥ Windows 核心编程 _ 进程五06/30
- ♥ 关于多字节和宽字节一11/10