如何在主线程中等待子线程完成,反之亦然?

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

在 C++ 中,我有一个更新函数,可以迭代立方体数组,应用物理原理,然后绘制:

Update()
   {
   for each cube in cubes:
   {
      DoPhysics(cube)
   }
   Draw()
}

我通过查找开始和结束迭代器将该数组拆分为多个等于线程数量的块。我将这些线程分离到 Update() 每个迭代器之间的多维数据集。

我想在主线程中等待所有子线程在绘图之前完成更新。我想在子线程中等待 main 完成绘制,然后再次更新。

Update(it start, it end)
{
   Wait Until (Main::Draw() is done)
   {
      for (it = start; it != end; it++)
      {
         DoPhysics(*it)
      }
   }
}

Update()
   {
   Wait Until (ALL Thread::Update() is done)
   {
      Draw()
   }
}

我尝试使用互斥体和条件变量来等待,但是由于您必须锁定互斥体才能使用 CV,所以我无法找到同时触发多个线程的方法。相反,它们会在等待时锁定,使每个线程依次触发。

我觉得我错过了一些东西,所以我想我应该在这里寻求帮助:也许有一个我忽略的明显方法,或者一个 std::something 可以帮助我。我对大学的截止日期感到非常厌倦,所以这是完全可能的。

c++ multithreading synchronization
1个回答
0
投票

您可以使用互斥体和可能的条件变量来实现这一点

应该 具有由共享变量

is_updated
is_drawn
定义的共享状态 并使用互斥类来保护它

  • 在主线程中,你还需要一个等待机制,以便之后 启动子线程,它会等到它们完成使用
    条件变量

  • 在子线程中向主线程发出信号,表明它们已完成,并等待主线程完成后再更新

这个东西:

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex updateMutex;
std::condition_variable updateCV;
bool isUpdated = false;

std::mutex drawMutex;
std::condition_variable drawCV;
bool isDrawn = false;

void DoPhysics(int& cube) {
    // Simulate physics
    // ...
}

void WorkerUpdate() {
    // Update logic

    {
        std::unique_lock<std::mutex> lock(updateMutex);
        isUpdated = true;
    }
    updateCV.notify_one();
}

void MainUpdate() {
    // Launch worker threads

    // Wait for worker threads to finish updates
    {
        std::unique_lock<std::mutex> lock(updateMutex);
        updateCV.wait(lock, [] { return isUpdated; });
    }

    // Draw logic

    {
        std::unique_lock<std::mutex> lock(drawMutex);
        isUpdated = false;
    }
    drawCV.notify_all();
}

int main() {
    // Launch MainUpdate in a separate thread
    std::thread updateThread(MainUpdate);

    // Launch worker threads
    std::thread workerThread(WorkerUpdate);

    // Join threads
    updateThread.join();
    workerThread.join();

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.