c++20 多线程并发 latch barrier semaphore

背景:

c++20 关于多线程并发新增了 latch, barrier, semaphore ,接下来就按照一个一个进行介绍

latch

latch 是一次性使用的线程协调点, 一旦给定数量的线程达到latch点时, 所有线程都会解除阻塞, 并继续执行. 基本上它是一个计数器, 在每个线程到达latch点时倒数, 一旦计数器达到0, latch 将无限制保持在一个有信号的状态, 所有阻塞线程都将解除阻塞, 随后到达latch点的任何线程会立刻被允许执行.

latch 由 std::latch实现, 在<latch> 中定义, 构造函数接收需要到达latch点的所需线程数, 到达latch点的线程可以调用arrive_and_wait(), 它递减latch 计数器并阻塞, 直到latch有信号为止. 线程也可以通过调用wait 在不减少计数器的情况下阻塞在latch点上, try_wait() 方法可用与检查计数器是否达到零, 最后如果需要,还可以通过count_down()来减少计数器, 而不会阻塞.

代码如下:

#include<latch>
#include <vector>
#include <iostream>
#include <thread>
#include <memory>
#include <chrono>int main()
{std::vector<std::jthread> threads;std::latch startLatch{ 1 };for (int i = 0; i < 10; ++i){threads.push_back(std::jthread{[i, &startLatch]{std::cout<< i <<" in wait" <<std::endl;startLatch.wait();std::cout<< i <<" runing" <<std::endl;}});}std::cout<<"start before"<<std::endl;std::this_thread::sleep_for(std::chrono::milliseconds(5));startLatch.count_down();std::cout<<"start after"<<std::endl;return 0;
}

clang++ -std=c++20 -pthread latch.cpp

barrier

barrier 是由一系列阶段组成的可重用线程协调机制, 允许多线程在barrier点阻塞. 当给定数量的线程到达barrier时,  将执行完成阶段的回调, 解除所有阻塞线程的阻塞, 重制线程技术器, 并开始下一个阶段. 在每隔阶段中, 可以调整下一个阶段的预期线程数. barrier对于在循环之间执行同步非常有用. 例如假设多线程并发执行, 并在一个循环中执行一些计算. 进一步假设一旦这些计算执行完成, 需要在线程开始其循环的新迭代之前对结果进一步处理. 对于这种情况, 设置barrier是完美的, 所有的线程都会阻塞在barrier处, 当它们全部到达时, 完成阶段回调将处理结果, 然后解除所有阻塞, 以开始它们的下一次迭代.

barrier 由 std::barrier实现, 在<barrier>中定义, barrier 最重要的方式是arrive_and_wait(), 他减少计数器, 然后阻塞线程, 直到当前阶段完成.

下边是具体代码示例

#include<thread>
#include<iostream>
#include<vector>
#include <chrono>
#include <barrier>
void completionFunction() noexcept 
{
}int main()
{const size_t numberOfThreads{4};std::barrier barrierPoint {numberOfThreads, completionFunction};std::vector<std::jthread> threads;for (int i = 0; i < numberOfThreads; ++i){threads.push_back(std::jthread{[i,&barrierPoint](std::stop_token token){while (!token.stop_requested()){std::cout<<i<<" in wait"<<std::endl;barrierPoint.arrive_and_wait();std::cout<<i<<" runing"<<std::endl;std::this_thread::sleep_for(std::chrono::milliseconds(1000));}}});}return 0;
}

clang++ -std=c++20 -pthread barrier.cpp

semphore

semphore 信号量 是轻量级同步原语, 可用作其他同步机制(如mutex, latch, barrier)的构建块. 基本上上一个semaphore由一个表示很多插槽的计数器组成. 计数器在构造函数中初始化. 如果获得了一个插槽, 计数器就减少, 而释放插槽将增加计数器. 在<semaphore>中定义了两个semaphore类, std::count_semaphore 和 binary_semaphore. 前一种模型是非负资源计数, 后者只有一个插槽, 该槽事空的, 要么不是空的, 完全适合作为互斥的构建快.

代码如下:

#include<iostream>
#include <semaphore>
#include <thread>
#include <vector>
int main()
{std::counting_semaphore semaphore{4};std::vector<std::jthread> threads;for (int i = 0; i < 4; i++){threads.push_back(std::jthread{[&semaphore](){semaphore.acquire();semaphore.release();}});}	
}

clang++ -std=c++20 -pthread barrier.cpp

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

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

相关文章

用Rust打印hello world!

步骤1 桌面新建1个名为 rustDemo 的文件夹&#xff08;文件夹名字随便取&#xff09; 步骤2 打开新建的文件夹&#xff0c;在地址输入栏输入 cmd 按回车键进入命令行窗口 步骤3 打开编译器&#xff0c;按 Ctrl S&#xff0c;保存文件到 rustDemo 文件夹中&#xff0c;保存的…

【git】从一个git仓库迁移到另外一个git仓库

在远端服务器创建一个新的仓库 用界面创建&#xff0c;当然也可以用命令创建 拉去源仓库 git clone --bare git192.168.10.10:java/common.gitgit clone --bare <旧仓库地址>拉去成功以后会出现 进入到文件夹内部 出现下面信息&#xff1a; 推送到新的远端仓库 git …

【IOTE】物联网射频模组和芯片级方案提供商——深圳信驰达科技将精彩亮相IOTE物联网展

►►►强势来袭 Strong Attack 主物联场&#xff0c;相约深圳&#xff1b;2023&#xff0c;共论商机&#xff01;IOTE2023第二十届国际物联网展深圳站将于2023年9月20-22日在深圳国际会展中心(宝安新馆)开展&#xff01;汇聚全球超800家参展企业&#xff0c;呈现更多数字化纷呈…

.NET Framework 微软官方下载地址

微软官方下载地址&#xff1a; 下载 .NET Framework | 免费官方下载 (microsoft.com) 版本发布日期终止支持.NET Framework 4.8.12022年8月9日.NET Framework 4.82019年4月18日.NET Framework 4.7.22018年4月30日.NET Framework 4.7.12017年10月17日.NET Framework 4.72017年…

ARM驱动开发

驱动 以来内核编译&#xff0c;依赖内核执行 驱动可以同时执行多份代码 没main 驱动是依赖内核的框架和操作硬件的过程 一&#xff0c;Linux系统组成 app: [0-3G] ---------------------------------系统调用&#xff08;软中断…

C# PaddleDetection yolo 印章检测

效果 项目 代码 using OpenCvSharp; using OpenCvSharp.Extensions; using Sdcb.PaddleDetection; using Sdcb.PaddleInference; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq…

chrono 模块学习

三大类 顶级clock: system_clock日期时间; steady_clock启动时间, 硬件震动clock; 内置四大类型: duration使用精度类型(min,sec,ms,ns等 加 数量); rep记录对应精度数量的类型(默认longlong, 也可以自定义其他类型); period: 精度, 即当前精度等于1s*ratio, (ms 1 / 1000s)…

【数据结构】 二叉树面试题讲解->贰

文章目录 &#x1f30f;引言&#x1f384;[二叉树遍历](https://www.nowcoder.com/practice/4b91205483694f449f94c179883c1fef?tpId60&&tqId29483&rp1&ru/activity/oj&qru/ta/tsing-kaoyan/question-ranking)&#x1f431;‍&#x1f464;题目描述&#…

Java 创建一个线程的方式

Java中创建线程主要有三种方式&#xff0c;分别为继承Thread类、实现Runnable接口、实现Callable接口。 继承Thread类&#xff0c;重写run()方法&#xff0c;调用start()方法启动线程 public class ThreadTest {/*** 继承Thread类*/public static class MyThread extends Thr…

1.(python数模)单函数读取常用文件

Python单函数读取常用文件 代码如下&#xff1a; import pandas as pd# 读取数据文件 def readDataFile(readPath): # readPath: 数据文件的地址和文件名try:if (readPath[-4:] ".csv"):dfFile pd.read_csv(readPath, header0, sep",") # 间隔符为逗…

音频——I2S TDM 模式(六)

I2S 基本概念飞利浦(I2S)标准模式左(MSB)对齐标准模式右(LSB)对齐标准模式DSP 模式TDM 模式 文章目录 TDM formatTDM format ATDM format BTDM format C总结 TDM format TDM 分为两种常用操作模式&#xff1a;TDM A mode 和 TDM B mode, 统称为TDM mode 基于 TDM mode&#x…

leetcode做题笔记114. 二叉树展开为链表

给你二叉树的根结点 root &#xff0c;请你将它展开为一个单链表&#xff1a; 展开后的单链表应该同样使用 TreeNode &#xff0c;其中 right 子指针指向链表中下一个结点&#xff0c;而左子指针始终为 null 。展开后的单链表应该与二叉树 先序遍历 顺序相同。 思路一&#x…

buuctf [CISCN 2019 初赛]Love Math

这题主要利用了php的一些特性 变量函数数字转字符串 源码 <?php error_reporting(0); //听说你很喜欢数学&#xff0c;不知道你是否爱它胜过爱flag if(!isset($_GET[c])){show_source(__FILE__); }else{//例子 c20-1$content $_GET[c];if (strlen($content) > 80) {…

【App端】uni-app使用百度地图api和echarts省市地图下钻

目录 前言方案一&#xff1a;echarts百度地图获取百度地图AK安装echarts和引入百度地图api完整使用代码 方案二&#xff1a;echarts地图和柱状图变形动画实现思路完整使用代码 方案三&#xff1a;中国地图和各省市地图下钻实现思路完整使用代码 前言 近期的app项目中想加一个功…

Uniapp笔记(四)uniapp语法3

一、商品详情 1、从商品列表页跳转到商品详情页 在商品列表的项中绑定单击事件&#xff0c;并传递商品id值 <view class"goods-item" v-for"(item,index) in goodsList" :key"index" click"goGoodsDetail(item.goods_id)"> &…

新版Mongodb(6.0以上)找不到mongo.exe

安装目录下/bin目录中&#xff0c;没有mongo.exe文件&#xff0c;只有mongod和mongos&#xff0c;以及一个powershell命令脚本。 原因在于&#xff0c;mongodb6.0以后做出了重大改变&#xff0c;mongodb已经不再默认为你安装shell工具&#xff0c;因此需要安装一个额外的shell…

FFmpeg5.0源码阅读——FFmpeg大体框架(以GIF转码为示例)

摘要&#xff1a;前一段时间熟悉了下FFmpeg主流程源码实现&#xff0c;对FFmpeg的整体框架有了个大概的认识&#xff0c;因此在此做一个笔记&#xff0c;希望以比较容易理解的文字描述FFmpeg本身的结构&#xff0c;加深对FFmpeg的框架进行梳理加深理解&#xff0c;如果文章中有…

基于负载均衡的在线OJ实战项目

前言&#xff1a; 该篇讲述了实现基于负载均衡式的在线oj&#xff0c;即类似在线编程做题网站一样&#xff0c;文章尽可能详细讲述细节即实现&#xff0c;便于大家了解学习。 文章将采用单篇不分段形式&#xff08;ps&#xff1a;切着麻烦&#xff09;&#xff0c;附图文&#…

javacv 基础04-读取mp4,avi等视频文件并截图保存图片到本地

javacv 读取mp4,avi等视频文件并截图保存图片到本地 代码如下&#xff1a; package com.example.javacvstudy;import org.bytedeco.javacv.FFmpegFrameGrabber; import org.bytedeco.javacv.Frame; import org.bytedeco.javacv.Java2DFrameConverter;import javax.imageio.Im…

Macos 10.13.2安装eclipse

eclipse for php 安装2021-12最后版本4.22 2021-12 R | Eclipse Packages jdk17 x64 dmg安装包,要安装jdk这个才能运行 Java Downloads | Oracle