您的位置:首页 > 编程语言

<<windows核心编程>>读书笔记---第8章 用户模式下的线程同步

2013-08-23 12:35 351 查看
前言:线程的同步,经常用的到的知识。

InterLocked函数:

LONG
InterlockedExchangeAdd(
IN OUT PLONG  Addend,
IN LONG  Value
);


以原子访问的方式来增减或者减少Target变量。value为正增加的值,为负则是减少的值。

LONG
InterlockedExchange(
IN OUT PLONG  Target,
IN LONG  Value
);


将Value的值赋给Target,并且返回Target的原来的值。

当然最强大的还有对链表的操作:



说实话这些函数我都没有用过。不过暂且做个记录吧,说不定哪天就用到了呢。

高速缓存行:其实当CUP从内存取回自己的时候,并不是取回一个字节,而是取回32位的整数倍的高速缓存行,这样,如果需要访问这个字节周围的字节,可以直接使用,大大增大了效率。如果单一的这么想确实会提高效率,可是如果是多核CPU,CPU1取出的高速缓存行,CPU2改变了该内存的值,CPU1没有得到更新,这样是很大的失误。因为CPU在设计的时候,如果有CPU改变告诉缓存行的内存,就会发送消息通知高速缓存行作废,然后重新获取高速缓存行,

所以,我们在定义结构体的时候,尽量的将只读的,只写的,不同的数据放在一起,这样会提高效率,因为改写比较大的数据可以放在同一个高速缓存行,实时进行更新,却不用动那些经常不变化的告诉缓存行。

想要获得CPU告诉缓存行的大小,可以调用GetLogicalProcessorInformation函数,该函数返回一个SYSTEM_LOGICAL_PROCESSOR_INFORMATION的结构体,该结构体的CACHE字段是一个CACHE_DESCRIPTOR结构,其中的LineSize字段表示CPU的高速缓存行的大小。(msdn中此函数有demo)

关键段和旋转锁:

定义CRITICAL_SECTION结构的变量,InitializeCriticalSection初始化该变量,把EnterCriticalSection和LeaveCriticalSection放在关键代码的首尾处,DeleteCriticalSection销毁该变量。

可惜无法在多个进程之间进行线程同步。

当一个线程拥有对资源的访问权的时候,如果另一个线程也调用EnterCritical想拥有资源,那么系统会将后者从用户状态转化为内核状态进行等待,当前者释放资源之后,系统会将后者转化为可调度状态并且更新CRITICAL_SECTION的值。不过,由于从用户状态转化为内核状态需要消耗很多的时间,很有可能在转换的时候,前者已经释放了资源。所以我们还是使用关键段+旋转锁一起使用。

当调用EnterCriticalSection的时候,他会用一个旋转锁不停的循环,尝试在一段时间内获的对该资源的访问权。只有当尝试失败的时候,线程才会切换到内核模式进入等待状态。

BOOL WINAPI InitializeCriticalSectionAndSpinCount(
__in_out      LPCRITICAL_SECTION lpCriticalSection,
__in          DWORD dwSpinCount
);


此函数用来初始化关键段,第一个参数为关键段的对象,第二个参数为旋转锁循环的次数。(如果为单任务处理器的话,第二个参数忽略)。参考值:保护进程堆的关键段4000

Slim读写锁:

其实Slim读写锁与上述的关键段性质类似,但是还有有所不同的:

Slim读写锁区分了读进程和写进程,因为单纯的读数据是不会破坏数据的。当写进程的时候,任何其它进程是无法共享该资源的。

首先,需要对SRWLOCK结构进行初始化

VOID WINAPI InitializeSRWLock(
__out         PSRWLOCK SRWLock
);


初始化完毕之后,写线程会调用AcquireSRWLockExclusive来独占共享资源。ReleaseAcquireSRWLockExclusive
读线程会调用AcquireSRWLockShared来共享资源。ReleaseSRWLockShared

对于Slim锁,也有其局限性:

1. 没有TryEnter(Shared/Exclusive)之类的函数,如果所已经被占用,那么调用AcquireSRWLockExclusive函数将会阻塞调用线程 。

2. 不可以循环嵌套使用。(有个queue的demo 以后再写,顺便当做复习)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: