多线程编程的基本概念,C++标准库中的多线程支持(std::thread,std::async),如何处理线程同步和并发问题。

多线程编程在现代计算机系统中非常重要,因为它能够使程序同时执行多个操作,提高计算效率。以下是多线程编程的基本概念及如何在C++标准库中使用std::threadstd::async进行多线程编程,同时处理线程同步和并发问题。

多线程编程的基本概念

  1. 线程(Thread):

    • 线程是一个轻量级的进程,是操作系统能够独立管理的基本单元。一个进程可以包含多个线程,这些线程共享进程的资源(如内存、文件句柄等)。
  2. 并发与并行(Concurrency vs. Parallelism):

    • 并发是指程序能够在同一时间处理多个任务。具体而言,虽然任务可能并不是同时运行的,但它们在程序中的执行顺序会交错进行。
    • 并行是指程序在同一时刻实际执行多个任务。并行通常需要多核处理器,多个任务真正同时进行。
  3. 线程安全(Thread Safety):

    • 当多个线程访问共享资源(如全局变量、文件等)时,如果没有适当的同步机制,就可能出现数据竞争(Data Race)和死锁(Deadlock)等问题。线程安全是指程序在多线程环境下运行时,能够正确地处理并发访问,不会出现错误。

C++ 标准库中的多线程支持

C++11引入了丰富的多线程支持,主要包括std::threadstd::async等工具。以下是它们的基本用法:

1. std::thread

std::thread提供了一个简单的接口来创建和管理线程。下面是一个基本的示例:

#include <iostream>
#include <thread>// 线程执行的函数
void print_hello() {std::cout << "Hello from thread!" << std::endl;
}int main() {// 创建线程并启动std::thread t(print_hello);// 等待线程完成t.join();std::cout << "Hello from main!" << std::endl;return 0;
}

在这个示例中,std::thread t(print_hello); 创建并启动了一个新线程来执行print_hello函数。t.join(); 用于等待线程t完成。

2. std::async

std::async是一个高层次的接口,用于启动异步任务,并且它返回一个std::future对象,用于获取异步任务的结果。下面是一个基本的示例:

#include <iostream>
#include <future>// 异步执行的函数
int compute_sum(int a, int b) {return a + b;
}int main() {// 使用 std::async 启动异步任务std::future<int> result = std::async(std::launch::async, compute_sum, 10, 20);// 获取异步任务的结果int sum = result.get();std::cout << "Sum is: " << sum << std::endl;return 0;
}

在这个示例中,std::async启动了一个异步任务来计算两个整数的和,并返回一个std::future对象result。通过调用result.get(),可以获得异步任务的结果。

线程同步和并发问题的处理

为了保证线程安全,需要使用同步机制来管理对共享资源的访问。C++标准库提供了一些常用的同步原语:

  1. 互斥量(Mutex):

    • std::mutex:用于在多个线程之间保护共享资源,确保一次只有一个线程可以访问资源。
    • std::lock_guard:用于简化互斥量的使用,在一个作用域内自动锁定和解锁互斥量。
      #include <iostream>
      #include <thread>
      #include <mutex>std::mutex mtx; // 互斥量void print_number(int n) {std::lock_guard<std::mutex> lock(mtx);std::cout << "Number: " << n << std::endl;
      }int main() {std::thread t1(print_number, 1);std::thread t2(print_number, 2);t1.join();t2.join();return 0;
      }
      

 

2.条件变量(Condition Variable):

  • std::condition_variable:用于线程间的通信,使一个线程能够等待另一个线程的某个条件满足。
  • std::unique_lock:用于与条件变量一起使用,能够更灵活地控制互斥量的锁定和解锁。

 

#include <iostream>
#include <thread>
#include <condition_variable>std::mutex mtx;
std::condition_variable cv;
bool ready = false;void print_message() {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, []{ return ready; }); // 等待条件满足std::cout << "Thread is running!" << std::endl;
}int main() {std::thread t(print_message);{std::lock_guard<std::mutex> lock(mtx);ready = true; // 设置条件为 true}cv.notify_one(); // 通知等待的线程t.join();return 0;
}

3.原子操作(Atomic Operations):

  • std::atomic:提供对基本数据类型的原子操作,避免使用锁的开销。
    #include <iostream>
    #include <thread>
    #include <atomic>std::atomic<int> counter(0);void increment() {for (int i = 0; i < 1000; ++i) {++counter;}
    }int main() {std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();std::cout << "Counter: " << counter.load() << std::endl;return 0;
    }
    

    在这个示例中,std::atomic<int> 保证了对 counter 的操作是线程安全的,不需要使用互斥量来保护它。

    通过正确地使用这些工具和同步机制,可以有效地管理多线程程序中的并发问题,提高程序的性能和可靠性。

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

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

相关文章

K8S学习教程(二):在 PetaExpress KubeSphere容器平台部署高可用 Redis 集群

前言 Redis 是在开发过程中经常用到的缓存中间件&#xff0c;为了考虑在生产环境中稳定性和高可用&#xff0c;Redis通常采用集群模式的部署方式。 在制定Redis集群的部署策略时&#xff0c;常规部署在虚拟机上的方式配置繁琐并且需要手动重启节点&#xff0c;相较之下&#…

十款绚丽的前端 CSS 菜单导航动画

CSS汉堡菜单是一种非常流行的PC端和移动端web菜单风格&#xff0c;特别是移动端&#xff0c;这种风格的菜单应用更为广泛。这款菜单便非常适合在手机App上使用&#xff0c;它的特点是当顶部菜单弹出时&#xff0c;页面内容将会配合菜单出现适当的联动&#xff0c;让整个页面变得…

关于linux捕捉鼠标事件的方法

网上找了很多方法&#xff0c;都比较杂乱。这篇文章专注于读取鼠标的动作&#xff1a;左键、右键、中键、滚轮。 linux的设备都以文件形式存放&#xff0c;要读取鼠标&#xff0c;有两种方法&#xff0c;一种是通过/dev/input/mice&#xff0c;一种是通过/dev/input/eventx (x…

探索线程安全:HashMap 的四种使用技巧

这篇文章&#xff0c;我们聊聊线程安全使用 HashMap 的四种技巧。 1 方法内部&#xff1a;每个线程使用单独的 HashMap 如下图&#xff0c;tomcat 接收到到请求后&#xff0c;依次调用控制器 Controller、服务层 Service 、数据库访问层的相关方法。 每次访问服务层方法 serv…

vue H5页面video 视频流自动播放, 解决ios不能自动播放问题

视频组件 <videostyle"width: 100%; height: 100%;object-fit: fill"class"player"refplayer_big_boxcontrolspreloadautoplay //自动播放muted //是否静音playsinline"true"x5-playsinline""webkit-playsinline"tru…

[Linux安全运维] Linux用户以及权限管理

Linux用户以及权限管理 Linux用户和组 用户信息文件pasawd /etc/passwd文件用于存储用户的信息 :用于分割不同的字段信息 字段示例&#xff08;第一行&#xff09;含义说明1root用户名2x密码占位符x代表用户有密码存储在shadow文件中无内容代表用户登录系统不需要密码30UID…

梧桐数据库:存算分离和存算一体架构的分布式数据库技术分析

摘要&#xff1a; 随着数据量的不断增长和对数据处理性能的要求越来越高&#xff0c;分布式数据库技术成为了数据存储和处理的重要解决方案。存算分离和存算一体是两种常见的分布式数据库架构&#xff0c;它们在数据存储和计算方面有着不同的特点和优势。本文将对存算分离和存算…

Spring源码(一) 如何阅读 Spring 源码

学习 Spring 的源码&#xff0c;也可以通过 SpringBoot 搭环境。 不管是什么源码&#xff0c;最好写个 demo&#xff0c;跑起来&#xff0c;然后从常用的类和方法入手&#xff0c;跟踪调试。 配置对象 新建一个 SpringBoot 的项目&#xff0c; 详情见&#xff1a; https://b…

FreeRTOS 中 vListInsertEnd 函数详解

在 FreeRTOS 中&#xff0c;vListInsertEnd 函数用于将新项插入到指定列表的尾部&#xff08;但实际行为是插入到一个特定的索引位置之前&#xff09;。FreeRTOS 使用双向链表&#xff08;doubly linked list&#xff09;来管理任务和其他系统对象&#xff0c;这样可以高效地插…

前端三件套开发模版——产品介绍页面

今天有空&#xff0c;使用前端三件套html、css、js制作了一个非常简单的产品制作页面&#xff0c;与大家分享&#xff0c;希望可以满足大家应急的需求。本页面可以对产品进行“抢购”、对产品进行介绍&#xff0c;同时可以安排一张产品的高清大图&#xff0c;我也加入了页面的背…

JAVA实现二分查找,斐波那契数列,深度优先搜索详情教程【包含代码】

本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明来源(注明:作者:王文峰…

react+ts+antd项目搭建

前言&#xff1a; 基于ts语言创建react项目&#xff0c;node版本是v16.14.2 一、 脚手架创建项目 全局安装 npm install -g creacte-react-app创建项目file-management&#xff0c;ts需要添加–template typescript npx create-react-app file-management --template typesc…

Ubuntu查看opencv版本c++

✗命令行中直接输入&#xff1a; pkg-config --modversion opencv✔命令行中直接输入&#xff1a; pkg-config --modversion opencv4注解&#xff1a;附上在markdown中打勾&#xff0c;对号和打叉。使用时将&和#之间的空格去掉&#xff0c;这里只是为了不让CSDN自动转换才…

Ubuntu20.04 c++程序 涉及opencv问题记录

头文件更改 默认的头文件引用是 #include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp>但是在ubuntu20中/usr/include中默认的是opencv4&#xff0c;他文件夹里面才是opencv2&#xff0c;需要…

vue3单个页面进行防抖节流

防抖 <template><button id"submitButton" ref"submitButton">GET</button> </template><script lang"ts" setup> import { ref, onMounted } from vue;// 防抖函数 function debounce(func: () > void, dela…

【mybatis】mybatis-plus中Wrapper(查询条件构造器)简介_常用方法

1、简介 MyBatis-Plus 是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。MyBatis-Plus 提供了强大的条件构造器&#xff08;Wrapper&#xff09;&#xff0c;用于构建复杂的 SQL 查询条件&#xff0c;使得我们…

沟通方法和技巧

0 Preface/Foreword 1 沟通对象 沟通维度&#xff1a; upward&#xff0c;向上沟通&#xff0c;直接上级downward&#xff0c;向下沟通&#xff0c;直接下级horizontal&#xff0c;横向沟通&#xff0c;同部门/跨部门同事 2 沟通方式&#xff08;5W2H&#xff09; 对于开会和…

小白尝试某程机票信息爬取

实训课需要机票数据集&#xff0c;网上没有&#xff0c;所以我选择爬取数据 此过程可谓经历的九九八十一难&#xff0c;也参考了不少大佬的文章&#xff0c;在此特别记录一下 弯路不多说&#xff0c;我直接讲成功的方法 找到请求url 通过控制台&#xff0c;最后确认下面的 …

在WordPress中获取10天之内的文章更新数

要在WordPress中获取10天之内的文章更新数&#xff0c;您可以使用以下代码片段。这段代码将显示在过去10天内更新的文章数量。 <?php // 获取当前时间戳 $now time();// 计算10天前的时间戳 $ten_days_ago $now - (10 * 24 * 60 * 60);// 设置查询参数 $args array(pos…

【Spring Boot AOP中切入表达式格式介绍】

文章目录 一、切入表达式简介二、切入表达式的语法1. 方法匹配符示例&#xff1a; 2. 类型匹配符示例&#xff1a; 一、切入表达式简介 切入表达式&#xff08;Pointcut Expression&#xff09;是AOP中定义切入点&#xff08;Pointcut&#xff09;的一种方式。它定义了在哪些连…