一种用于多线程中间状态同步的屏障机制

news/发布时间2024/8/25 18:06:44

一种用于多线程中间状态同步的屏障机制

为了解决在多线程环境中,需要一个内置的计数屏障对于多个线程中的某一个部分进行检查,确保所有线程均到达该点后才能继续执行。

该屏障常被用于多线程流水线中的中间检查,适用于阶段分割,是一种有效的同步机制。

此处构建了一个barrier类,其中arrive_and_wait()函数是对应的屏障方法,work是测试线程。

此处代码注释掉的是使用busy-wait进行循环的忙等版本,保留了使用条件变量和unique_lock的阻塞wait_for版本,可以对比两者之间的性能差距。

一般来说,线程规模较小,任务量较少时busy-wait效率较高,是由于sleep-awake过程中有系统调用。当任务规模达到一定程度时,wait_for通常性能较好。

代码如下:

#include <thread>
#include <unistd.h>
#include <vector>
#include <cstddef>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include "barrier.hpp"class barrier {
public:barrier(size_t expected):_expected(expected),_arrived(0),_passed(0){}void arrive_and_wait();private:const size_t _expected;std::atomic<size_t> _arrived;std::atomic<size_t> _passed;std::mutex mtx;std::condition_variable cv;
};/*void barrier::arrive_and_wait()
{auto passed = _passed.load();if (_arrived.fetch_add(1) == _expected - 1) {// NOTE: reset *before* incrementing, otherwise we might reset to zero a// thread already waiting on the next wave_arrived = 0;_passed++;} else {while (_passed.load() == passed) {// busy-wait}}
}*/void barrier::arrive_and_wait()
{auto passed = _passed.load();if (_arrived.fetch_add(1) == _expected - 1) {// NOTE: reset *before* incrementing, otherwise we might reset to zero a// thread already waiting on the next wave_arrived = 0;_passed++;cv.notify_all();} else { //blockstd::unique_lock<std::mutex> lck(mtx);cv.wait(lck, [&] {return _passed.load() != passed;});lck.unlock();cv.notify_all();}
}void work(size_t id, barrier& b)
{printf("+%ld\n", id); fflush(stdout);b.arrive_and_wait();printf(".%ld\n", id); fflush(stdout);b.arrive_and_wait();printf("-%ld\n", id); fflush(stdout);
}int main(int argc, char** argv)
{auto nthreads = atoi(argv[1]);barrier b(nthreads);std::vector<std::thread> threads;for (auto i = nthreads; i; i--) {threads.emplace_back(work, i, std::ref(b));}for (auto& thread : threads) {thread.join();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.liansuoyi.cn/news/44236671.html

如若内容造成侵权/违法违规/事实不符,请联系连锁易网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

机器视觉:摄像机标定技术

机器视觉:摄像机标定技术 https://mp.weixin.qq.com/s/UGkYtGsGsgiiCzsaYlkx4g 空间物体表面某点的三维几何位置与其在图像中对应点之间的相互关系是由摄像机成像的几何模型决定的,这些几何模型参数就是摄像机参数,为了得到这些参数而进行的实验与计算的过程称为摄像机标定。…

代码随想录第三天 | 203.移除链表元素 707.设计链表 206.反转链表

LeetCode:203. 移除链表元素 - 力扣(LeetCode)思路:移除链表只是跳过需要移除的链表即可,即cur=cur.next 有关虚拟头结点:首先要建立一个结点作为虚拟头结点,也就是在head前加一个,然后因为虚拟头和一会要遍历的指针指向的内容不能变,所以用cur代替head,pre也就是虚拟…

时间回溯(物品)

展示思路 将作用物体的每帧信息存储在一个容器中,在时间回溯时逆序地读取容器中的信息; 步骤 1.创建以下项结构体:用于存储每帧信息; ActorComponent(下文使用AC代替):存放功能逻辑; 接口:用于角色调用AC; 回溯Actor:AC作用的Actor; 角色蓝图的操作逻辑:用于触发回…

飞剑

思路 创建单独的飞剑Actor,并在其中编写飞剑本身行为的脚本,然后在玩家角色蓝图中编写发射行为的脚本 效果展示步骤详述 1.角色蓝图中添加Spline组件2.创建飞剑的Actor3.角色蓝图中添加发射技能的脚本Tips:简单的材质修改

一道图的题

最近遇到的一道算法题: 有一个坐标系,输入一组数据input:, eg: const input = [[0, 0],[1, 1],[3, 1],[1, 2],[3, 2],[2, 3],[1, 4],[2, 4],[4, 4],[4, 5],[3, 4] ];input的每个值(数组)是一组坐标,对应到图是这样的,输出为: output: [[[0, 0]],[[1,1], [1,2]],[[3,1], [3…

P4983 忘情 题解

题目链接:忘情 大概是本题为数不多的李超树解法,凸包显然太经典,不再赘述。 先考虑简化原式,看看一个区间段的 \(val\) 这一大坨简化后是啥: \[\dfrac{((\sum_{i=1}^{n}x_i\times \overline{x})+\overline{x})^2}{\overline{x}^2},观察到分母有个\ \overline{x}^2,我们分子…

Lua学习笔记

Lua学习笔记 lua的基本语法和数据类型在Lua中,最重要的线程是协同程序(coroutine)它跟线程(thread)差不多,拥有自己独立的栈、局部变量和指令指针,可以跟其它协同程序共享全局变量和其它大部分东西。 线程和协程的区别:线程可以同时运行多个,而协程任意时刻只能运行一…

【HFSS】仿真显示方向图E面和H面

1. 建立远端辐射场2. 设置远端辐射方向图对于我仿真的天线模型,E面是phi=0,theta:0-360,H面是phi=90,theta:0-360; 配置内容E面方向图H面方向图但是当H面和E面在一个坐标里H面的方向图不同,原因是scale坐标不相同解决办法,扩大H面的scale的值

Unity如何从0实现技能CD遮罩

需求描述我们需要实现一个类似英雄联盟中的技能CD遮罩,施放技能后,技能遮罩占满技能图标,随着时间推移,技能遮罩顺时针减少遮挡面积,CD结束时,遮罩应完全消失。 需求分析 由于每个时刻,都会有一条线从中心点射向上面那条边的中点,我们自然可以想到将遮罩面片分为8个三角…

Dr4g0nB4ll - Vulnhub靶机

Dr4g0nB4ll - Vulnhub靶机 主机发现 192.168.30.133信息收集 └─$ nmap -sV -A 192.168.30.133 Starting Nmap 7.94 ( https://nmap.org ) at 2024-02-22 03:26 EST Nmap scan report for 192.168.30.133 Host is up (0.0013s latency). Not shown: 998 closed tcp ports (con…

[LitCTF 2023]导弹迷踪

查看源代码,下滑到最下面,看到很多.js文件

3分钟看懂设计模式01:策略模式

一、什么是策略模式 定义一些列算法类,将每一个算法封装起来,并让它们可以互相替换。 策略模式让算法独立于使用它的客户而变化,是一种对象行为型模式。 以上是策略模式的一般定义,属于是课本内容。 在没有真正理解策略模式之前并不需要对此定义下过多功夫,读一遍直接进入…

day39 动态规划part2 代码随想录算法训练营 62. 不同路径

day39 动态规划part2 代码随想录算法训练营 62. 不同路径题目:62. 不同路径 我的感悟:加油!武汉下冻雨是真冷呀!!理解难点:dp的含义, dp这里加的含义 dp外层是m,是深度,内层是n是长度 从1开始遍历,而不是从0.听课笔记:代码示例: class Solution:def uniquePaths(se…

PHP常用环境套件

当你学习来了PHP之后,你就知道PHP套件的必要性,在学习php时,我们不能在php环境安装上花费很长时间,这是得不偿失的;也没必要花费几百购买php空间。这时我们需要在自己的电脑上安装php环境套件,那么php环境套件有哪些?1、php环境——XAMPP 是一款比较强大的本地测试平台,…

pve 将硬盘挂载到ct容器

1. 配置文件方法 vi /etc/pve/lxc/101.conf #101是ct容器编号 mp0: /mnt/pve/hdd4, mp=/mnt/hdd4t mp1: /mnt/pve/hdd6, mp=/mnt/hdd6t mp2: /mnt/pve/sdd, mp=/mnt/sdd1t 配置信息如图:配置完成后,可在容器资源里看到挂载信息:然后重启容器即可。

Blocks(单调栈)

题干中说每次选择一个大于k的数,还要选他左右两个数其中之一加上一,最后问你最长的每个数不小于K的子序列。 这些都是障眼法,其实就是问你最长的平均值大于或等于K的最长子序列,这样就明朗了。 接下来就是找子序列的问题,因为要求的是区间最大平均值,所以不能再以单个数的…

自动驾驶4D毫米波雷达研究综述(续)

自动驾驶4D毫米波雷达研究综述(续) https://arxiv.org/pdf/2306.04242.pdf 4D Millimeter-Wave Radar in Autonomous Driving: A Survey 摘要——能够测量目标的距离、方位、仰角和速度的4D毫米波雷达引起了自动驾驶界的极大兴趣。这归功于其在极端环境中的稳健性以及卓越的速…

烽火HG6143中国电信光猫超级密码获取

一:开启光猫Telnet浏览器访问:http://192.168.1.1:8080/cgi-bin/telnetenable.cgi?telnetenable=1&key=XXXXXX192.168.1.1为你的路由器IP地址XXXXXX这里替换为光猫MAC地址,去掉冒号,去掉冒号,去掉冒号查看设备MAC地址: 开启成功界面会显示“telnet开启”。二:电脑…

中国电信HG6143烽火光猫超级密码获取

一:开启光猫Telnet浏览器访问:http://192.168.1.1:8080/cgi-bin/telnetenable.cgi?telnetenable=1&key=XXXXXX192.168.1.1为你的路由器IP地址XXXXXX这里替换为光猫MAC地址,去掉冒号,去掉冒号,去掉冒号查看设备MAC地址: 开启成功界面会显示“telnet开启”。二:电脑…
推荐文章