一个没有任何访问控制的循环锁必然不是线程安全的
bool bEnter = false;
while(bEnter)
// do something
bEnter = true;
因为无法控制bEnter被多个线程改写其值
采用InterlockedExchang控制的循环锁则能解决该问题
LONG lEnter = 0;
while(InterlockedExchange(&lEnter, 1) == 1) Sleep(0);
// do something
InterlockedExchange(&lEnter, 0);
此处需要注意几点:
1. InterlockedExchange的返回值为指定的LONG变量被修改前的值
2. Sleep(0) 可以给其他线程提供抢占的机会
之前觉得这段代码其实并不安全 因为InterlockedExchange的返回值可能不准确
例如线程1的
while(InterlockedExchange(&lEnter, 1) == 1) Sleep(0);
InterlockedExchange的返回值虽然为0
但是
LONG lEnter;
有可能已经被其他线程修改为1了
这时候判断就不准确了
但是想了想应用场景就是这个while循环而已
假如多个线程都并发到InterlockedExchange 但只会有一个线程进入
这时的InterlockedExchange返回0
这使得当前线程可以从while循环中unblock出来
进入下面的执行流程
但其他的线程因为LONG lEnter已经被修改为1
其InterlockedExchange返回也为1 依然被block在while循环中
直到修改了LONG lEnter的线程重新把该值置0为止
所以不存在并发时 InterlockedExchange的返回值被其他修改的情况
以上红色部分的描述仅仅针对这个循环锁的应用场景而言
但要注意一点 这种循环锁会浪费CPU时间