C++ 提供调度提示以调度到 std::thread 的下一个线程

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

我有多个线程同时处理不同的问题。

有时一些线程正在等待其他线程的结果,其状态由布尔变量设置。

当一个线程必须等待另一个线程的结果时,我会这样做:

while(!finished)
{
    std::this_thread::sleep_for(std::chrono::milliseconds(1));
}

我正在寻找一种更好的方法来通知调度程序继续下一个线程。像这样的东西:

while(!finished)
{
    schedular.schedule();
}

向调度程序发出信号表明当前线程没有更多事情可做并且应该继续下一个线程的最佳方法是什么?

c++ multithreading scheduler
1个回答
1
投票

您当前使用的方法

std::this_thread::sleep_for
会引入不必要的延迟和 CPU 使用率,即使睡眠持续时间很短也是如此。处理这种情况的更好方法是使用 C++ 标准库提供的同步原语,例如
std::condition_variable
。这些允许线程有效地等待,将执行交给调度程序,直到收到通知为止。

使用
std::condition_variable

以下是如何使用

std::condition_variable
重写代码:

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

std::atomic<bool> finished{false}; // Atomic variable for thread-safe status
std::mutex mtx;                    // Mutex to protect condition variable
std::condition_variable cv;        // Condition variable for signaling

void worker_thread() {
    // Simulate some work
    std::this_thread::sleep_for(std::chrono::seconds(2));

    // Notify that the work is finished
    {
        std::lock_guard<std::mutex> lock(mtx);
        finished = true;
    }
    cv.notify_one(); // Notify waiting thread
}

void waiting_thread() {
    // Wait for the result
    std::unique_lock<std::mutex> lock(mtx);
    cv.wait(lock, [] { return finished.load(); }); // Wait until finished is true

    std::cout << "Work is finished, proceeding..." << std::endl;
}

int main() {
    std::thread t1(worker_thread);
    std::thread t2(waiting_thread);

    t1.join();
    t2.join();

    return 0;
}

如何运作:

  1. 条件变量 (

    std::condition_variable
    ):

    • cv.wait
      方法有效地将线程置于睡眠状态并在等待时释放互斥锁上的锁。
    • 仅当调用
      cv.notify_one
      cv.notify_all
      时才会唤醒线程,与忙等待循环相比,减少了 CPU 使用率。
  2. 原子变量 (

    std::atomic<bool>
    ):

    • 确保
      finished
      标志以线程安全的方式更新,而不需要额外的同步。
  3. 互斥 (

    std::mutex
    ):

    • 保护对共享状态 (
      finished
      ) 的访问,并且是
      std::condition_variable
      所必需的。

优点:

  • 效率:线程不会循环旋转,而是处于休眠状态,直到收到通知。
  • 调度程序友好:它允许线程完全放弃执行,直到有有意义的工作要做。
  • 可扩展:处理多个线程而不会产生过多的 CPU 开销。

在处理相互依赖结果的线程时,推荐使用此模式。它最大限度地减少 CPU 使用率并利用操作系统高效的线程调度机制。

© www.soinside.com 2019 - 2024. All rights reserved.