Window进程内多线程同步

处于同一进程内的多线程数据同步有一下几种方式:

1、InterLock系列函数

主要用于单个资源的同步

2、旋转锁

单CPU的机器,不要使用自旋锁,会出现死锁的状态。(因为当前线程一直在锁内旋转,单个CPU是没有机会切换到另一个线程中进行执行)


3、volatile关键字

如果没有可用的同步方式时,可以使用volatile进行同步。(这种方式很劣势,当两个线程不在同一优先级上,会出现死锁)


4、关键段(CRITICAL_SECTION)

关键段的初始化和反初始化

void initializeCriticalSection(PCRITICAL_SECTION cs);

void DeleteCriticalSection(PCRITICAL_SECTION cs);


a.阻塞模式的关键段使用:(会让调用者线程进入等待状态)

EnterCriticalSection( cs );

//需要同步的资源

LeaveCriticalSection( cs );


b.非阻塞模式的关键段使用:(不会让调用者线程进入等待状态,可以访问资源就访问,否则立即执行下面的代码)

if( TryEnterCriticalSection(sc) == TRUE) {

//需要同步的资源

LeaveCriticalSection( cs );

}


c. 阻塞模式的关键段会将调用者线程从用户模式切换到内核模式,这种切换的代价很大;如果是多CPU的机器就有点浪费,可能当前占用资源的线程在另一个CPU上运行,而且很快就会结束对资源的访问。这时,我们使用带旋转锁的关键段最后,调用线程如果在制定的旋转次数能还没获取资源的访问权,则线程才进入等待状态。

使用下面的初始化函数来初始化一个带旋转锁的关键段:

BOOL InitializeCriticalSectionAndSpinCount(PCRITICAL_SECTIONcs, DWORDdwSpinCount); 如果在单CPU机器上dwSpinCount会被忽略,总是为0.

更改关键段的旋转次数(参考值4000):

DWORD SetCriticalSectionSpinCount(PCRITICAL_SECTION cs, DWORD dwSpinCount); 跟上面一样,如果单CPU环境,会忽略掉dwSpinCount参数。


5、读/写锁SRWLock

通过读写锁将想要读取资源的线程和更新资源的线程分开。只有在写入者线程更新资源时,才需要同步;此时,写入者线程对资源具有独占权限,读取者线程是无法访问资源。

VOID InitializeSRWLock(PSRWLOCK SRWLock);  //初始化读写锁

写锁访问资源;

VOID AcquireSRWLockExclusive(PSRWLOCK SRWLock);

//对资源进行写操作

VOID ReleaseSRWLockExclusive(PSRWLOCK SRWLock);


读锁访问资源:

VOID AcquireSRWLockShared(PSRWLOCK SRWLock);

//对资源进行读访问

VOID ReleaseSRWLockShared(PSRWLOCK SRWLock);


6、条件锁(这是一种高级锁):

案例:如果读取者线程没有数据可以读取,那么它应该将锁释放并等待,直到写入者线程残生了新的数据为止。如果,用来接收写入者线程产生的数据已满,那么写入者线程应该释放掉锁,并进入等待状态,直到读取者线程把数据清空为止。

对于上面的案例,此时使用关键段和读写锁已经不行了;好的是Windows提供条件锁来同步这种操作。线程可以以原子方式把锁释放并将自己阻塞,直到某一条件成立为止。

BOOL SleepConditionVariableCS(...);

BOOL SleepConditionVariableSRW(...);


当另一个线程检测到相应的条件已经满足的时候,比如存在一个元素可让读取者线程读取,或者有足够的空间让写入者线程插入新的线程,它会调用下面的函数。

VOID WakeConditionVariable(PCONDITION_VARIABLE ConditionVariable);

VOID WakeAllConditionVariable(PCONDITION_VARIABLE ConditionVariable);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值