实施“睡眠”的正确方法是什么?使用C ++的技术?

时间:2018-01-17 18:49:22

标签: c++ multithreading

两个帖子。主要是不断收集通知,而另一个正在处理其中一些通知。 我实施它的方式 - 不正确,因为我被告知。它造成了什么问题以及它有什么问题?

#include <iostream>
#include <atomic>
#include <thread>
#include <mutex>
#include <chrono>

std::condition_variable foo;
std::mutex mtx;

void secondThread()
{
    while (true)
    {
            foo.wait(std::unique_lock<std::mutex>(mtx));
            std::cout << " ----------------------------" << std::endl;
            std::cout << "|processing a notification...|" << std::endl;
            std::cout << " ----------------------------" << std::endl;
    }
}
int main()
{
    std::thread subThread = std::thread(&secondThread);
    int count = 0;
    while (true)
    {
        if (count % 10 == 0)
        {
            foo.notify_one();
        }
        std::cout << "Main thread working on gathering notifications..." << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(300));
        count++;
    }
    return 0;
}

根据C ++规范,有人告诉我这个foo.wait(std::unique_lock<std::mutex>(mtx))代码行不是一个好习惯。这不是解决此类问题的正确方法。它也叫,睡觉(不忙等待)。

1 个答案:

答案 0 :(得分:2)

在致电wait之前,您必须检查您正在等待的事情是否已经发生。在您停止致电wait之前,您必须检查您正在等待的事情。条件变量是无状态的,不知道你在等什么。编写代码是你的工作。

此外,关联的互斥锁必须保护您正在等待的内容。条件变量的整个要点是提供原子“解锁和等待”操作以防止出现此问题:

  1. 您是否需要在互斥锁的保护下等待。
  2. 您认为确实需要等待。
  3. 解锁互斥锁,以便其他线程可以取得进展。
  4. 你等。
  5. 但是如果您在等待互联网之前解锁互斥锁之后发生了什么事情呢?你会等待已经发生的事情。

    这就是wait函数获取锁持有者的原因 - 这样它就可以原子地执行步骤3和4。