简体   繁体   English

最后一个 notify_all 没有触发最后一个 conditional_variable.wait

[英]Last notify_all isn't triggering last conditional_variable.wait

What I'm Trying To Do我想做什么

Hi, I have two types of threads the main one and the workers where the workers are equal to the number of cores on the CPU, what I'm trying to do is when the main thread needs to call an update I set a boolean called Updating to true and call condition_variable(cv).notify_all then each thread will do its work and when done it will increment by one an atomic_int called CoresCompleted followed by a cv.notify_all so that the main thread can check if all the work is done then it will wait for the variable Updating to be false so it is sure that all other threads finished and it doesn't update again, once everything is done the main thread sets updating to false and notifies all.嗨,我有两种类型的线程,主要线程和工作线程,其中工作线程等于 CPU 上的内核数,我想做的是当主线程需要调用更新时,我设置了一个 boolean 调用更新为 true 并调用condition_variable(cv).notify_all然后每个线程将完成其工作,完成后它将增加一个名为atomic_int的 atomic_int,然后是cv.notify_all以便主线程可以检查是否所有工作都已完成它将等待变量 Updating 为 false,因此可以确保所有其他线程都已完成并且不会再次更新,一旦完成所有操作,主线程就会将 updating 设置为 false 并通知所有线程。

CODE代码

Main主要的

void UpdateManager::Update() {

    //Prepare Update
    CoresCompleted = 0;
    Updating = true;

    //Notify Update Started
    cv.notify_all();

    //Wait for Update to end
    auto Pre = high_resolution_clock::now();
    cv.wait(lk, [] { return (int)UpdateManager::CoresCompleted >= (int)UpdateManager::ProcessorCount; });
    auto Now = high_resolution_clock::now();
    auto UpdateTime = duration_cast<nanoseconds>(Now - Pre);
    
    //End Update and nofity threads
    Updating = false;
    cv.notify_all();
}

Workers工人

void CoreGroup::Work() {

    Working = true;
    unique_lock<mutex> lk(UpdateManager::m);

    while (Working) {
        
        //Wait For Update To Start
        UpdateManager::cv.wait(lk, []{ return UpdateManager::Updating; });

        if (!Working)
            return;

        //Do Work
        size_t Size = Groups.size();

        auto Pre = high_resolution_clock::now();

        for (size_t Index = 0; Index < Size; Index++)
            Groups[Index]->Update();

        auto Now = high_resolution_clock::now();
        UpdateTime = duration_cast<nanoseconds>(Now - Pre);
        
        //Increment CoresCompleted And Notify All
        UpdateManager::CoresCompleted++;
        UpdateManager::cv.notify_all();

        //Wait For Update To End
        UpdateManager::cv.wait(lk, []{ return !UpdateManager::Updating; });
    }
}

Problem问题

Once the workers reach the last wait where they wait for Updating to be false they get stuck and never leave, for some reason the last notify_all in the main thread is not reaching the workers, I tried searching and looked for many examples but I can't figure out why it isn't triggering, maybe I miss understood how the cv and lock works, any ideas why this is happening and how to fix?一旦工作人员到达他们等待更新为假的最后等待,他们就会卡住并且永远不会离开,由于某种原因主线程中的最后一个 notify_all 没有到达工作人员,我尝试搜索并寻找很多例子但我不能'不知道为什么它没有触发,也许我想念 cv 和锁的工作原理,知道为什么会发生这种情况以及如何解决?

Here is how your code works: some waiting in Update is over when notified:以下是您的代码的工作原理:收到通知时,一些等待Update的操作已经结束:

cv.wait(lk, [] { return (int)UpdateManager::CoresCompleted >= (int)UpdateManager::ProcessorCount; });

It goes out of waiting and requires the lock on the mutex.它停止等待并需要锁定互斥锁。 Proceed to do its stuff then reaches the end and notifies the other thread that they can continue working with this line:继续做它的事情然后到达终点并通知另一个线程他们可以继续使用这一行:

cv.notify_all();

But it lies, they can't continue working because you hold the lock.但这是谎言,他们不能继续工作,因为你持有锁。 Release it and they will proceed working:释放它,他们将继续工作:

void UpdateManager::Update() {
    <...>
    //End Update and nofity threads
    Updating = false;
    lk.unlock();
    cv.notify_all();
}

That probably isn't the only issue in this code but I assume that you lock the mutex before entering the Update method or have some guarantee that it runs before the other one ( Work ).这可能不是此代码中的唯一问题,但我假设您在进入Update方法之前锁定了互斥锁,或者保证它在另一个方法 ( Work ) 之前运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM