C++并发编程(1)-- 多线程的基础知识

news2024/12/28 21:41:11

1 进程、线程和协程

(1)进程

进程可以简单理解成正在执行的一个程序,比如你电脑上运行的QQ、360杀毒软件等就是进程。

进程是程序资源管理的最小单位。

进程会管理那些资源呢?通常包括内存资源、IO资源、信号处理等。

这里对内存资源简单介绍下。

操作系统采用虚拟内存技术,把进程虚拟地址空间划分成用户空间和内核空间。内核空间是操作系统内核访问的区域,独立于普通的应用程序,是受保护的内存空间。

用户空间是普通应用程序可访问的内存区域。用户空间又分成5个不同的内存区域,分别是:

栈、堆、数据段、BSS段和代码段。

(2)线程

线程是操作操作系统能够进行运算调度的最小单位。线程被包含在进程之中,是进程中的实际运作单位,一个进程内可以包含多个线程,线程是资源调度的最小单位,CPU上真正运行的是线程。

同一进程中的多条线程共享该进程中的全部系统资源,如虚拟地址空间,文件描述符文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈、寄存器环境、线程本地存储等信息。

线程创建的开销主要是线程堆栈的建立,分配内存的开销。这些开销并不大,最大的开销发生在线程上下文切换的时候。

线程是被内核所调度,线程被调度切换到另一个线程上下文的时候,需要用户态到内核态转换,开销比较多。

(3)协程

协程 (Coroutines) 是一种比线程更加轻量级的微线程。类比一个进程可以拥有多个线程,一个线程也可以拥有多个协程,因此协程又称微线程和纤程。

协程的调度完全由用户控制,协程拥有自己的寄存器上下文和栈,协程调度切换时,直接操作用户空间栈,完全没有内核切换的开销。

2 并发(concurrency)和并行(parallelism)

并发在CPU层面其实是交替执行的,比如有2个任务A和B,CPU一会儿执行A,一会儿又执行B,不停地在2个任务之间切换。因为CPU执行的速度很快,切换间隔非常短,所以在我们看来任务A和B在同时进行。而并行是真正的同时执行。

3 临界区

临界区用来表示一种共享资源。它可以被多个线程使用,但同一时刻只能被一个线程使用。一旦临界区资源被某个线程占用,其他线程就必须等待。

4 阻塞(blocking)和非阻塞(non-blocking)

阻塞和非阻塞用来形容多线程间的相互影响。

(1)阻塞

比如一个线程占用了临界区资源,那么其他需要这个资源的线程就必须等待,等待会导致线程挂起,这种情况就是阻塞。

(2)非阻塞

非阻塞指线程间相互不影响,所有线程都在尝试不断向前执行。

5 同步(synchronous)和异步(asynchronous)

同步和异步用来形容方法的一次调用。

(1)同步

同步方法调用一旦开始,调用者必须等待调用返回后,才能继续执行后面的任务。

(2)异步

而异步方法调用无需等待,在调用后直接返回,调用者可以继续做其他的任务。

6 死锁(deadlock)、饥饿(starvation)和活锁(livelock)

死锁、饥饿和活锁属于多线程的活跃性问题。

(1)死锁

死锁是最糟糕的一种情况,比如线程A持有了线程B的锁,而线程B持有了线程A的锁,而双方又同时在等待对方持有的锁。

(2)饥饿

饥饿指某个线程可能因为优先级比较低等原因,导致它一直无法得到资源,所以没法执行。

(3)活锁

活锁就好像是两个人走路碰面了,这个时候相互谦让让路,结果又碰上了。这样就会导致资源不断在两个线程之间来回跳动,而没有一个线程能同时拿到所有资源而正常执行。

7 原子性(atomicity)、可见性(visibility)和有序性(ordering)

(1)原子性

原子性指一个操作是不可中断的。假如有一个变量a,两个线程同时对它赋值,比如线程A给它赋1,线程B给它赋2,那么不管是怎样的情况,变量a的值要么是1,要么是2,不会是其他值。这就是原子性的一个特点。

(2)可见性

可见性指当线程A修改了某个变量的值后,线程B是否能够马上看到修改后的值。

在串行执行时,当前面修改了变量的值后,后面的代码肯定能马上得到修改后的值。但在并发环境中,线程B读到的变量的值,不一定是线程A刚写进去的值。

(3)有序性

为了优化程序性能,编译器和处理器可能会对指令序列进行重排序,也就是你编写的代码顺序和最终执行的指令顺序是不一致的。比如下面的2条指令:

int a = 1;
bool flag = true;

可能会被重排序成这样:

bool flag = true;
int a = 1;

重排序不会使串行执行的程序逻辑发生变化,也就是说在一个线程中重复执行被重排序的代码后,得到的结果永远是相同的;但重排序可能会导致多线程程序出现内存可见性问题。

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

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

相关文章

众和策略:华为汽车概念活跃,圣龙股份斩获12板,华峰超纤涨10%

华为轿车概念23日盘中再度生动,到发稿,华峰超纤涨超10%,佛山照明、圣龙股份、隆基机械、银宝山新等涨停,赛力斯涨近6%。 值得注意的是,圣龙股份已接连12个交易日涨停。 昨日晚间,圣龙股份宣布前三季度成果…

Cisco交换机关于DHCP SNOOPING的配置指令

在Cisco交换机上配置DHCP Snooping(DHCP欺骗防护) DHCP Snooping的作用 DHCP Snooping是一项重要的网络安全功能,可用于维护网络的安全性和可靠性,减少潜在的网络问题,并提供日志和监控功能,以便网络管理…

【Servlet】实现Servlet程序

文章目录 1. 最朴素方式1. 创建项目2. 引入依赖3. 创建目录4. 编写代码5. 打包程序6. 部署程序7. 验证程序 2. 更方便方式1. 安装Smart TomCat插件2. 启动 1. 最朴素方式 1. 创建项目 选择Maven项目 2. 引入依赖 Maven项目创建完后会生成一个pom.xml文件,我们可…

rancher2.6.4配置管理k8s,docker安装

docker快速安装rancher并管理当前k8s集群。 1、拉镜像 docker pull rancher/rancher:v2.6.4 2、启动rancher 启动很慢 --privileged必须拥有root权限,并挂载卷 docker run --privileged -d --restartunless-stopped -p 80:80 -p 443:443 -v /usr/local/docker_vo…

rocketmq集群部署DLedger Controller

目录 rockermq集群部署DLedger Controller到官网下载rockermq集群模式:3切片主从建目录配置Nameserver先修改内存 启动NameServer停止NameServer配置Broker启动Broker启动管制台直接docker 启动即可,修改 -e 后面 nameserver 参数即可端口列表导入 rocke…

h5插件_h5页面嵌入客户端调试

当h5页面嵌入客户端之后&#xff0c;若是遇到问题无法调试&#xff0c;比如点击按钮无反应 —> 但是开发却看不到控制台、看不到接口返回值… 此时可以使用调试工具来查看… edura 引入1 <script src"https://cdn.jsdelivr.net/npm/eruda"></script&g…

向某文件中逐秒追加带序号输入当前时间 fgets fputs fprintf sprintf

//向某文件中逐秒追加带序号输入当前时间 #include<stdio.h> #include<stdlib.h> #include<time.h> #include<string.h> #include <unistd.h> int main(int argc, char const *argv[]) { time_t tv; // time(&tv);//法1:获取秒数 …

2023面试经典 Redis未授权漏洞与组合拳

文前漫谈 之前面试里碰见过&#xff0c;属于面试经典了&#xff0c;有空了了解一下 2015年的洞了&#xff0c;从以前乌云一个师傅的文章那了解到 Redis 有关的漏洞具有明显的时间分段性&#xff0c;在15年11月之前&#xff0c;主要是未授权导致的数据泄露&#xff0c;获得一些…

自增还是UUID,数据库主键的类型该如何选择?

一、自增(auto_increment)和UUID优缺点 自增 &#xff08;auto_increment&#xff09;的优点: 1.字段长度较uuid小很多&#xff0c;可以是bigint甚至是int类型&#xff0c;这对检索的性能会有所影响。 2.在写的方面&#xff0c;因为是自增的&#xff0c;所以主键是趋势自增的&…

小游戏外包开发流程及费用

小游戏的开发流程和费用会因项目的规模、复杂性和所选技术平台而有所不同。以下是一般的小游戏开发流程和可能的费用因素&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 开发流程&#xff1a; 概念和…

Android Studio Gradle中没有Task任务,没有Assemble任务,不能方便导出aar包

Gradle中&#xff0c;没有Assemble任务 1. 在编译aar包或者编译module的时候&#xff0c;没有release包&#xff0c;我们一般都是通过assemble进行编译。 如果在Gradle中找不到task。 可以通过设置File->setting -->Experimental→取消勾选“Do not build Gradle task …

TransactionScope的使用

TransactionScope的使用 简介1. 命名空间2.创建事务范围3.嵌套事务4.事务提交和回滚5.支持分布式事务6.配置选项7.资源管理器8.分布式事务协调器 应用1.未设置分布式事务2.设置分布式事务 简介 TransactionScope 是 .NET Framework 和 .NET Core 中的一个类&#xff0c;用于简化…

Java数组—精讲篇

Java数组—精讲篇 先进行专栏介绍 二维数组定义格式初始化静态初始化动态初始化 举例声明并初始化一个3行4列的整型二维数组访问二维数组元素访问二维数组array中第2行第3列的元素 遍历二维数组遍历二维数组array并打印每个元素的值强调 应用举例总结 程序展示二维数组元素打乱…

ThingsBoard的版本控制整合gitee

1、注册gitee账号,创建自己的空间,并且创建一个用于存储ThingsBoard相关的仓库 2、进入ThingsBoard的租户层,然后找到版本控制,进行配置 输入gitee的仓库地址 仓库URL:指定你的gitee的参考地址 仓库分支:master 身份验证:密码、访问令牌 用户名:登录账号 密码/访问令…

【LeetCode刷题】1两数之和

为找工作&#xff0c;我的代码都是用的JAVA&#xff0c;慢慢学习中。 LeetCode刷题Day1 两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入…

【干货】Java函数式编程公式大全,收藏学习!

函数操作是现代编程领域中的核心概念之一&#xff0c;它以类似 Excel 表格的方式进行数据处理和计算。它的特点是使用公式和函数来描述数据之间的关系和计算逻辑&#xff1b;它允许我们以更高效、更有组织的方式管理和处理数据。 在函数式编程中&#xff0c;数据被组织成表格的…

UDP网络通信反复发收

package UDP2;import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.Scanner;/* * 完成UDP 通信快速入门 实现发1收1*/ public class Client {public static void main(String[] args) throws Exception{// …

统信操作系统UOS上安装arm64版nginx

原文链接&#xff1a;统信操作系统UOS上安装arm64版nginx hello&#xff0c;大家好啊&#xff0c;今天给大家带来一篇在统信桌面操作系统UOS上安装arm64版nginx的文章&#xff0c;本篇文章主要是给大家提供一种下载离线nginx软件包的方法&#xff0c;拿到软件包可以去不能链接互…

Qt耗时操作添加动画等待加载效果

Qt耗时操作添加动画等待加载效果_qt 等待动画-CSDN博客本例模拟耗时请求实现动画等待加载效果&#xff0c;采用QtConcurrent::run实现异步耗时操作&#xff0c;通过QFutureWatcher异步监测耗时操作结果的返回值做相应的动画演示。_qt 等待动画https://blog.csdn.net/qq_3666686…

解决AndroidStudio Gradle只有testDebugUnitTest

问题复现&#xff1a; 问题解决&#xff1a; 1:点击Task list not built... 2:取消勾选Configure all Gradle tasks during Gradle Sync... 大功告成&#xff0c;现在去看看Gradle&#xff0c;屏蔽的都显示出来了。