c++

Mutex and CV

Posted by keming on August 15, 2021
  • 为什么condition_variable要与mutex联用

https://www.cnblogs.com/Dahaka/archive/2012/02/19/2358528.html

  • cv的过程

https://www.jianshu.com/p/a31d4fb5594f

  • 自旋锁与普通mutex的区别
    • 自旋锁在等待的时候一直占用cpu,但是一旦等到了,时间开销更小。
    • mutex底层似乎有一小段时间的自旋,等不到才休眠,等待唤醒,时间开销长,cpu占用少。
  • unique_lock与lock_guard
    • 前者开销稍大,但更灵活,随时加解锁。

保证三个任务的顺序

  • 用condition_variable实现wait 和notify
namespace MT {
static mutex m1;
static condition_variable cv2;
static condition_variable cv3;
static int count = 0;	// 必不可少
void DoTask1();
void DoTask2();
void DoTask3();
}  // namespace MT

namespace MT {

void DoTask1() {
    unique_lock<mutex> ul(m1);
    cout << 1 << endl;
    count++;
    cv2.notify_one();
}

void DoTask2() {
    unique_lock<mutex> ul(m1);
    if (count != 1) {	// 如果task2就是第二个执行,那它不会被task1通知到,所以需要一个判断跳过去
        cv2.wait(ul);
    }
    
    cout << 2 << endl;
    count++;
    cv3.notify_one();
}

void DoTask3() {
    unique_lock<mutex> ul(m1);
    if (count != 2) {
        cv3.wait(ul);
    }
    
    cout << 3 << endl;
    count++;
}
}  // namespace MT

int main() {
    vector<thread> ths;
    ths.emplace_back(MT::DoTask1);
    ths.emplace_back(MT::DoTask2);
    ths.emplace_back(MT::DoTask3);

    for (auto &t : ths) {
        t.join();
    }

    return 0;
}
  • 为了放在虚假唤醒,判断cv的条件一般不用if,而会使用while