Windows 临界区

windows 临界区与 std::mutex 类似,效果几乎可以等同于 std::mutex

不过 Windows临界区,同一个线程是可以重复进入的,但是进入的次数与离开的次数必须相等。

std::mutex 则不允许同一个线程重复加锁。

windows中的临界区同 mutex 一样,可以保护一个代码段。但 windows 的临界区可以进入多次,离开多次,但是进入的次数与离开的次数必须相等,不会引起程序报异常出错。

自动析构技术

C++:lock_guard 防止忘了释放信号量,自动释放
windows:可以写个类自动释放临界区:

1
2
3
4
5
6
7
8
9
10
11
12
13
class CWinLock {        
public:
CWinLock(CRITICAL_SECTION *pCritmp) : m_pCritical(pCritmp)
{
EnterCriticalSection(m_pCritical);
}
~CWinLock()
{
LeaveCriticalSection(m_pCritical);
}
private:
CRITICAL_SECTION *m_pCritical;
};

上述这种类 RAII 类(Resource Acquisition is initialization),即”资源获取及初始化“。容器,智能指针属于这种类。

递归独占互斥量 std::recursive_mutex

std::mutex 独占式互斥量

std::recursive_mutex:允许在同一个线程中同一个互斥量多次被 lock() ,(但是递归加锁的次数是有限制的,太多可能会报异常),效率要比 std::mutex 低。

如果你真的用了 recursive_mutex 要考虑代码是否有优化空间,如果能调用一次 lock() 就不要调用多次。

带超时的互斥量 std::timed_mutex 和 std::recursive_timed_mutex

std::timed_mutex 与 std::mutex 类似,只是多了几个成员函数

  1. try_lock_for(): 参数是一段时间,等待一段时间,如果我拿到了锁,或者等待超过时间没拿到锁,就继续流程,返回值为 bool 类型

    1
    2
    3
    4
    5
    std::timed_mutex my_mutex;
    if(my_mutex.try_lock_for(std::chrono::milliseconds(100)) // 等待 100ms
    {
    //...
    }

    在规定时间内返回 true 否则返回 false

  2. try_lock_until(): 参数是一个未来的时间点,在这个现在这个时间到指定的未来时间内拿到锁,或者超过指定的时间没拿到锁就会继续流程,返回值为 bool 类型

    1
    2
    3
    4
    5
    std::timed_mutex my_mutex;
    if(my_mutex.try_lock_until(chrono::steady_clock::now() + 10s))
    {
    // ...
    }

    两者的区别就是一个参数是时间段,一个参数是时间点

std::recursive_timed_mutex:是待超时的递归独占互斥量 与 std::recursive_mutex 类似