[C++11 多线程同步] --- 线程同步概述

news/2024/4/30 3:48:23/文章来源:https://blog.csdn.net/weixin_42445727/article/details/127163522

1 线程调度的几个基本知识点

多线程并发执行时有很多同学捋不清楚调度的随机性会导致哪些问题,要知道如果访问临界资源不加锁会导致一些突发情况发生甚至死锁。

关于线程调度,需要深刻了解以下几个基础知识点:

  • 调度的最小单位是轻量级进程或者线程;
  • 每个线程都会分配一个时间片,时间片到了就会执行下一个线程;
  • 线程的调度有一定的随机性,无法确定什么时候会调度;
  • 在同一个进程内,创建的所有线程除了线程内部创建的局部资源,进程创建的其他资源所有线程共享; 比如:主线程和子线程都可以访问全局变量,打开的文件描述符等。

2 为什么需要线程同步

假设有 4 个线程 A、B、C、D,当前一个线程 A 对内存中的共享资源进行访问的时候,其他线程 B, C, D 都不可以对这块内存进行操作,直到线程 A 对这块内存访问完毕为止,B,C,D 中的一个才能访问这块内存,剩余的两个需要继续阻塞等待,以此类推,直至所有的线程都对这块内存操作完毕。 线程对内存的这种访问方式就称之为线程同步,通过对概念的介绍,我们可以了解到所谓的同步并不是多个线程同时对内存进行访问,而是按照先后顺序依次进行的

下面看一段代码说明为什么需要线程同步,两个线程对一个共享数据进行++操作并且输出出来,代码如下:

#include <iostream>
#include <thread>
#include <unistd.h>using namespace std;
int share = 0;  //共享变量
void thread1()
{for (int i = 0; i < 100; i++){int tmp = share;tmp++;usleep(10);share = tmp;cout << "thread1: share is " << share << endl;}
}
void thread2()
{for (int i = 0; i < 100; i++){int tmp = share;tmp++;usleep(200);share = tmp;cout << "thread2: share is " << share << endl;}
}int main()
{thread task1(thread1); thread task2(thread2); task1.join();task2.join();
}   

随机运行一次,结果如下:
在这里插入图片描述

可以看到,不但出现两个线程读取的变量值一样的现象(我们当然期望的是每一行都是一个唯一的数字并且有一个换行),还出现了cout的内容包括数字和换行符位置也有些错乱。主要原因是share和cout的缓冲区是thread1和thread2共享的,由于两个线程同时运行,便可能将一个已经修改的值读取,或者将另一个线程已经读取但是未修改的值进行读取,还有可能将另一个线程已经放入缓冲区的内容输出。当然,这个输出是不符合我们预期的!

3 线程同步的四种方式

对于多个线程访问共享资源出现数据混乱的问题,需要进行线程同步。常用的线程同步方式有四种:互斥锁、读写锁、条件变量、信号量。所谓的共享资源就是多个线程共同访问的变量,这些变量通常为全局数据区变量或者堆区变量,这些变量对应的共享资源也被称之为临界资源
找到临界资源之后,再找和临界资源相关的上下文代码,这样就得到了一个代码块,这个代码块可以称之为临界区。确定好临界区(临界区越小越好)之后,就可以进行线程同步了。
线程同步的大致处理思路是这样的:

  • 在临界区代码的上边,添加加锁函数,对临界区加锁。
    哪个线程调用这句代码,就会把这把锁锁上,其他线程就只能阻塞在锁上了。
  • 在临界区代码的下边,添加解锁函数,对临界区解锁。
    出临界区的线程会将锁定的那把锁打开,其他抢到锁的线程就可以进入到临界区了。
  • 通过锁机制能保证临界区代码最多只能同时有一个线程访问,这样并行访问就变为串行访问了。

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

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

相关文章

移动接入及核心网与移动回传网无信息交互,造成资源浪费

芯片处理能力、终端能力增强 随着智能终端的普及和用户需求的不断发掘&#xff0c;终端芯片和能力都有了飞 速的发展。从 3GPP 的标准化历程来看&#xff0c;终端可以支持的频带数组合增多、 物理层功能不断增强、支持的特性极速增长&#xff0c;当然也伴随着计算存储资源的 叠…

网络规划与部署—ACL命名实验

作者简介&#xff1a;一名在校计算机学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.命名ACL 二.标准命名的配置命令 三.ACL命名实验 1.实验要求 2.配置…

部署Apache Flink伪集群

一、准备Apache Flink运行环境 为了运行Flink,只需提前安装好 Java 11。你可以通过以下命令来检查 Java 是否已经安装正确。 1.1 Java 11下载 下载地址:https://www.oracle.com/java/technologies/downloads/#java11 1.2 Java 11安装 sudo rpm -i jdk-11.0.16.1_linux-x6…

大厂SQL题2-多表关联、转化率、打标签

一、红包流向 1.1 某表数据中不在另一个表中出现过的比例 红包发送方用户的基本信息缺失率有多高&#xff1f;&#xff08;即有多少红包发送方用户无法在用户基本信息表中匹配&#xff1f;&#xff09; 筛选出相关字段–左连接–不出现的即会为空—用count&#xff08;1&…

Codeforces Round #785 (Div. 2)

A. Subtle Substring Subtraction 题目链接&#xff1a;Problem - A - Codeforces 样例输入&#xff1a; 5 aba abc cba n codeforces样例输出&#xff1a; Alice 2 Alice 4 Alice 4 Bob 14 Alice 93题意&#xff1a;给定一个长度为n的字符串&#xff0c;然后Alice和Bob轮流…

【JavaDS】浅谈集合LinkedList的使用

✨博客主页: XIN-XIANG荣 ✨系列专栏:【Java实现数据结构】 ✨一句短话: 难在坚持,贵在坚持,成在坚持! 文章目录一. 什么是LinkedList?二. LinkedList的使用1. 构造方法2. 常用方法3. LinkedList的遍历三. ArrayList和LinkedList的区别一. 什么是LinkedList? LinkedList的底…

什么是虚拟计算机集群

这个问题来自近期几位网友的私信&#xff0c;他们不约而同问到一个问题&#xff1a;什么是虚拟计算机集群&#xff1f;Laxcus分布式操作系统是如何做的&#xff1f;下面就正式回答一下这个问题。 在我们传统的认知里&#xff0c;或者大家平常比较多接触的&#xff0c;都…

Linux基本使用

文章目录一.Linux的安装1.Linux系统的安装方式2.网卡设置3.安装SSH连接工具4.Linux和Windows目录对比二.Linux命令1.Linux常用命令2.文件目录操作命令三.软件安装1.软件安装方式一.Linux的安装 1.Linux系统的安装方式 &#xff08;1&#xff09;物理机安装&#xff1a;直接将…

NVMe系列专题之六:电源管理

NVMe协议其中有一项优势,就是低功耗!为了达成这个目标,NVMe中加入了自动电源状态转换和动态电源管理机制。 先来看一下NVMe Spec中对动态电源管理的描述图: 1. Host设定性能和功耗: Power Objective和Performance Objective。 2. Host通知Controller更改设备的power state。…

tf.pad()

参考 tf.pad - 云社区 - 腾讯云 tf.pad(tensor,paddings,modeCONSTANT,nameNone,constant_values0 )pad一个张量。 这个操作根据指定的paddings填充一个tensor。padding是一个形状为[n, 2]的整数张量&#xff0c;其中n是张量的秩。对于输入的每个维度D&#xff0c;paddings[D, …

Python数据分析之单变量分析

0 引言 在数据分析或者机器学习过程中&#xff0c;我们需要对变量或者特征进行分析&#xff0c;在分析过程中&#xff0c;一般都会分为两种&#xff1a;单变量分析、双变量分析。今天&#xff0c;土豆简单介绍一下单变量分析&#xff0c;单变量分析主要对单个变量或者特征进行…

基金入门笔记

什么是基金 基金概念【fund】为了某种目的设立的具有一定规模的资金&#xff08;保险金、公积金也可以理解为其中的一种&#xff09;但是平常说的指的是证券投资基金。证券包含债券 股票和期货。而证券投资基金是由基金公司 保险工资或者银行推出的 从众多投资者处募集巨额资金…

【易购管理系统】导航折叠效果

在el-menu中添加 v-model“isCollapse” <el-menu router"true"default-active"/"class"el-menu-vertical-demo"background-color"#545c64"text-color"#fff"active-text-color"#ffd04b"v-model"isCollap…

[Java]通过反射获取运行时类的对象及其内部结构

文章目录1. 创建运行时类的对象2. 体会反射的动态性3. 通过反射获取运行时类的结构3.1 用于测试的类的准备3.2 获取运行时类的属性3.2.1 getFields()3.2.2 getDeclaredField()3.2.3 获取属性的结构3.3 获取运行时类的方法3.3.1 getMethods()3.3.2 getDeclaredMethods()3.3.3 获…

美食篇:大闸蟹与梭子蟹的区别

文章目录大闸蟹梭子蟹区别总结吃蟹子的季节大闸蟹 梭子蟹 区别总结 大闸蟹香&#xff0c;小&#xff0c;有黄 梭子蟹鲜&#xff0c;大&#xff0c;无黄 小的梭子蟹也有黄&#xff0c;小的便宜 总结&#xff1a;浓缩的都是精华&#xff01;个头大的不一定好吃&#xff0c;但一…

面积结构设计

面积结构设计 针对面积的拓扑是尽可能最大程度地复用逻辑资源,常常以流量(速度)为代价。 1、折叠流水线 折叠流水线可以优化在流水线赋值逻辑的流水线设计的面积。 定点的分数乘法器。A表示定点刚好在最低有效位(LSB)右边的归一化整数格式,输入B的定点刚好在最高有效…

Torch

张量 Tensor torch.is_tensor[source] torch.is_tensor(obj) 如果obj是一个pytorch张量&#xff0c;则返回True torch.is_storage(obj) torch.set_default_tensor_type(t) 设置pytorch中默认的浮点类型&#xff0c;一般使用pytorch进行运算时候使用的都是浮点数来进行计算…

Linux进程(冯诺依曼体系结构、操作系统、进程)

文章目录一、冯诺依曼体系结构&#xff1a;1.基本概念&#xff1a;2.为什么如此设计&#xff1a;2.1.运行速度优化&#xff1a;2.2.成本&#xff1a;3.总结&#xff1a;二、操作系统&#xff1a;1.基本概念&#xff1a;2.操作系统的作用&#xff1a;3.什么是管理&#xff1a;三…

【Shell编程】Bash变量-用户自定义变量

目录系列文章Bash变量-用户自定义变量变量的命名规则变量分类本地变量实例系列文章 【Shell编程】Shell基本概述与脚本执行方式 【Shell编程】Shell中Bash基本功能 Bash变量-用户自定义变量 变量的命名规则 不能以数字开头在Bash中&#xff0c;变量的默认类型都是字符串型&…

关于XShell下载安装和连接Ubuntu(linux)

目录 1.XShell下载和安装 其实很多CSDN博主已经发表很多关于这个下载安装和连接的问题&#xff0c;但是我发现都是不完整的&#xff0c;所以自己再根据大佬写的&#xff0c;重新总结一下。 XSheel下载地址 XSheel安装教程 XShell连接的话看下面的教程&#xff0c;上面中的X…