条件变量是否真的需要另一个变量?

问题描述 投票:0回答:1

注:我将用C ++给出示例,但我相信我的问题与语言无关。如果我错了,请纠正我。

只是您真的很了解我-我想在这里学习的是工具的作用,仅此而已。不是平常使用的工具,不是约定所说的,而是钝工具的作用。在这种情况下-条件变量的作用。

到目前为止,在我看来,这是一种简单的机制,它允许线程等待(阻塞),直到其他线程向它们发出信号(取消阻塞)为止。仅此而已,不需要处理关键部分访问或数据访问(当然它们可以用于此操作,但这只是程序员的选择)。而且,通常仅在发生重要事件(例如,加载数据)时才进行信令,但是理论上可以在任何时间调用它。到目前为止正确吗?

现在,我所看到的每个示例都使用条件变量对象(例如std::condition_variable),还使用一些附加变量来标记是否发生了某些事情(例如bool dataWasLoaded)。在https://thispointer.com//c11-multithreading-part-7-condition-variables-explained/中查看此示例:

#include <iostream>
#include <thread>
#include <functional>
#include <mutex>
#include <condition_variable>
using namespace std::placeholders;
class Application
{
    std::mutex m_mutex;
    std::condition_variable m_condVar;
    bool m_bDataLoaded;
public:
    Application()
    {
        m_bDataLoaded = false;
    }
    void loadData()
    {
        // Make This Thread sleep for 1 Second
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        std::cout << "Loading Data from XML" << std::endl;
        // Lock The Data structure
        std::lock_guard<std::mutex> guard(m_mutex);
        // Set the flag to true, means data is loaded
        m_bDataLoaded = true;
        // Notify the condition variable
        m_condVar.notify_one();
    }
    bool isDataLoaded()
    {
        return m_bDataLoaded;
    }
    void mainTask()
    {
        std::cout << "Do Some Handshaking" << std::endl;
        // Acquire the lock
        std::unique_lock<std::mutex> mlock(m_mutex);
        // Start waiting for the Condition Variable to get signaled
        // Wait() will internally release the lock and make the thread to block
        // As soon as condition variable get signaled, resume the thread and
        // again acquire the lock. Then check if condition is met or not
        // If condition is met then continue else again go in wait.
        m_condVar.wait(mlock, std::bind(&Application::isDataLoaded, this));
        std::cout << "Do Processing On loaded Data" << std::endl;
    }
};
int main()
{
    Application app;
    std::thread thread_1(&Application::mainTask, &app);
    std::thread thread_2(&Application::loadData, &app);
    thread_2.join();
    thread_1.join();
    return 0;
}

现在,除了std::condition_variable m_condVar之外,它还使用一个附加变量bool m_bDataLoaded。但是在我看来,执行mainTask的线程已经通过std::condition_variable m_condVar通知了数据已加载。为什么还要检查bool m_bDataLoaded以获取相同信息?比较(不带bool m_bDataLoaded的相同代码):

#include <iostream>
#include <thread>
#include <functional>
#include <mutex>
#include <condition_variable>
using namespace std::placeholders;
class Application
{
    std::mutex m_mutex;
    std::condition_variable m_condVar;
public:
    Application()
    {
    }
    void loadData()
    {
        // Make This Thread sleep for 1 Second
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        std::cout << "Loading Data from XML" << std::endl;
        // Lock The Data structure
        std::lock_guard<std::mutex> guard(m_mutex);
        // Notify the condition variable
        m_condVar.notify_one();
    }
    void mainTask()
    {
        std::cout << "Do Some Handshaking" << std::endl;
        // Acquire the lock
        std::unique_lock<std::mutex> mlock(m_mutex);
        // Start waiting for the Condition Variable to get signaled
        // Wait() will internally release the lock and make the thread to block
        // As soon as condition variable get signaled, resume the thread and
        // again acquire the lock. Then check if condition is met or not
        // If condition is met then continue else again go in wait.
        m_condVar.wait(mlock);
        std::cout << "Do Processing On loaded Data" << std::endl;
    }
};
int main()
{
    Application app;
    std::thread thread_1(&Application::mainTask, &app);
    std::thread thread_2(&Application::loadData, &app);
    thread_2.join();
    thread_1.join();
    return 0;
}
  1. 现在,我了解了虚假唤醒,仅它们一个就需要使用其他变量。我的问题是-他们的[[仅他们原因吗?如果没有发生,可以只使用条件变量而无需任何其他变量(顺便说一句,这不会使“条件变量”名称误称)吗?]
  2. 另一件事是-使用附加变量不是条件变量也需要互斥量的唯一原因吗?如果没有,还有其他原因吗?
  3. 如果需要其他变量(出于虚假唤醒或其他原因),API为什么不要求它们(在第二个代码中,我不必使用它们进行编译)?
  4. (我不知道其他语言是否相同,所以这个问题可能是> C ++特定的。)
注:我将用C ++给出示例,但我相信我的问题与语言无关。如果我错了纠正我。正是您真正理解了我-我想在这里学习的是该工具的功能,并且...
multithreading language-agnostic condition-variable
1个回答
0
投票
并不仅涉及虚假唤醒。
© www.soinside.com 2019 - 2024. All rights reserved.