C++barrier线程同步屏障C++20

2026-04-02 01:00:26 1631阅读 0评论

C++20 Barrier 线程同步屏障

在现代多核处理器系统中,线程并发执行已成为常态。为了确保多个线程在特定点上同步,避免竞态条件和数据竞争,C++标准库提供了多种同步机制。其中,std::barrier 是C++20引入的一种强大工具,用于实现线程间的同步屏障。

什么是 std::barrier

std::barrier 是C++20中引入的一个同步原语,它允许一组线程在某个点上等待,直到所有线程都到达该点后,它们才能继续执行。这个点被称为“屏障”,std::barrier 的作用是确保所有线程在同一时间点上同步。

std::barrier 的基本用法

要使用 std::barrier,你需要包含头文件 <barrier>,并创建一个 std::barrier 对象。以下是一个简单的示例:

#include <iostream>
#include <thread>
#include <barrier>

void worker(std::barrier& barrier, int id) {
    std::cout << "Thread " << id << " is working..." << std::endl;
    // 模拟工作
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout << "Thread " << id << " has finished working." << std::endl;

    // 到达屏障
    barrier.arrive_and_wait();
    std::cout << "All threads have reached the barrier." << std::endl;
}

int main() {
    const int num_threads = 4;
    std::barrier barrier(num_threads);

    std::vector<std::thread> threads;
    for (int i = 0; i < num_threads; ++i) {
        threads.emplace_back(worker, std::ref(barrier), i);
    }

    for (auto& thread : threads) {
        thread.join();
    }

    return 0;
}

在这个示例中,我们创建了一个包含4个线程的屏障。每个线程在完成工作后调用 barrier.arrive_and_wait() 方法,表示它已经到达了屏障。当所有线程都到达屏障时,屏障会自动解除,所有线程可以继续执行后续代码。

std::barrier 的构造函数

std::barrier 的构造函数接受两个参数:

  1. count:表示需要到达屏障的线程数量。
  2. completion_token:一个可选的完成令牌,默认值为空。
std::barrier barrier(count, completion_token);
  • count:指定需要到达屏障的线程数量。
  • completion_token:当所有线程都到达屏障时,会调用这个令牌。默认情况下,所有线程都会被唤醒并继续执行。

std::barrier 的成员函数

std::barrier 提供了一些成员函数来管理屏障的状态:

  • arrive_and_wait():当前线程到达屏障并等待其他线程。
  • arrive_and_drop():当前线程到达屏障但不等待其他线程,屏障会被丢弃。
  • wait():当前线程等待其他线程到达屏障。

std::barrier 的应用场景

std::barrier 可以用于各种并发编程场景,例如:

  1. 任务分发:将一个大任务分成多个小任务,每个线程负责一个小任务,所有线程完成后,再合并结果。
  2. 数据同步:确保多个线程在处理共享数据时同步,避免数据竞争。
  3. 阶段同步:在多阶段任务中,确保每个阶段的所有线程都完成了当前阶段的任务后再进入下一阶段。

示例:任务分发

假设我们需要计算一个大型数组的平方和,我们可以将数组分成多个部分,每个线程计算一部分的平方和,最后将结果合并。

#include <iostream>
#include <thread>
#include <barrier>
#include <vector>

const int array_size = 1000000;
const int num_threads = 4;

std::vector<int> array(array_size);
std::vector<long long> partial_sums(num_threads, 0);

void compute_partial_sum(std::barrier& barrier, int start, int end, int id) {
    for (int i = start; i < end; ++i) {
        partial_sums[id] += array[i] * array[i];
    }
    barrier.arrive_and_wait();
}

int main() {
    std::barrier barrier(num_threads);

    std::vector<std::thread> threads;
    int chunk_size = array_size / num_threads;
    for (int i = 0; i < num_threads; ++i) {
        int start = i * chunk_size;
        int end = (i == num_threads - 1) ? array_size : (start + chunk_size);
        threads.emplace_back(compute_partial_sum, std::ref(barrier), start, end, i);
    }

    for (auto& thread : threads) {
        thread.join();
    }

    long long total_sum = 0;
    for (long long sum : partial_sums) {
        total_sum += sum;
    }

    std::cout << "Total sum of squares: " << total_sum << std::endl;

    return 0;
}

在这个示例中,我们将数组分成4个部分,每个线程计算一部分的平方和,最后将结果合并。

总结

std::barrier 是C++20中引入的一种强大的同步原语,适用于需要线程间同步的场景。通过使用 std::barrier,你可以简化并发编程中的同步问题,提高程序的可维护性和性能。希望本文能帮助你更好地理解和使用 std::barrier

文章版权声明:除非注明,否则均为Dark零点博客原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
验证码
评论列表 (暂无评论,1631人围观)

还没有评论,来说两句吧...

目录[+]