☰
  • 首页
  • 规则分类
  • 项目介绍
search
•••

避免虚假唤醒造成同步错误

16.7 ID_spuriouslyWakeUp
目录 › next › previous

条件不满足时条件变量也可以被唤醒,这种情况称为“虚假唤醒(spurious wakeup)”,条件变量被唤醒后应检查相关条件是否满足,否则会造成同步相关的错误。

示例:

mtx_t m;    // Mutex
cnd_t cv;   // Condition variable
bool cnd;   // Represents the condition

void thd() {                 // Thread function
    mtx_lock(&m);            // Lock
    if (!cnd) {              // Non-compliant, use a while loop instead
        cnd_wait(&cv, &m);   // Wait
    }
    ....
}

设例中 cv 是条件变量,cnd 代表相关条件,cnd_wait 等待条件被其他异步过程满足,条件的判断与更改应是互斥的,cnd_wait 会解锁并进入等待状态,当得到 cnd_signal 或 cnd_broadcast 的通知后会退出等待状态并再次加锁,但在条件不满足时也可能退出等待,原因主要有:

  • 一个条件变量对应多个条件,与当前条件无关的条件被满足并通知了条件变量
  • 在退出等待并加锁的过程中其他线程使条件不被满足
  • 等待过程被信号打断

这些问题取决于程序和系统的具体实现,在循环中等待并判断条件可一并解决这些问题:

void thd() {
    mtx_lock(&m);
    while (!cnd) {           // Compliant
        cnd_wait(&cv, &m);
    }
    ....
}

参考

SEI CERT CON36-C SEI CERT CON54-CPP
Copyright©2024 360 Security Technology Inc., Licensed under the Apache-2.0 license.