线程间的同步、如何解决线程冲突与死锁
一、线程同步概念:
线程同步是指在多线程编程中,为了保证多个线程之间的数据访问和操作的有序性以及正确性,需要采取一些机制来协调它们的执行。在多线程环境下,由于线程之间是并发执行的,可能会出现竞争条件(Race Condition)等问题,从而导致程序的不稳定性和错误。
案例与猜想:
示例1:
#include <iostream>
#include <windows.h>int g;DWORD WINAPI MyThreadProc (LPVOID lp){for(int i = 0; i < 100000000; i++){g++;}return 0;
}int main(){HANDLE h = CreateThread(NULL, 0, MyThreadProc, NULL, 0, 0);for(int i = 0; i < 100000000; i++){g++;}std::cout << g << std::endl;CloseHandle(h);return 0;
}
结果:

这里测试了两个次,当多个线程同时对公共资源进行操作时,会发生错误,该示例结果始终处在
100000000~200000000之间
猜测一:主线程可能先走完,然后输出g,并退出。
示例2:
因此在这里继续添加一个等待线程函数(WaitForSingleObject)等待线程结束试试

发现依旧无法达到预期。
猜测二:线程与线程之间存在同步,使得g在某一个或某一些值时,g在主线程与线程中,只增加一次。
二、解决方法
常见的线程同步机制包括:
1. 互斥锁(Mutex):互斥锁是一种保护共享资源的机制,它确保在任意时刻只有一个线程能够访问被保护的资源。当一个线程获得了互斥锁,其他线程就需要等待锁的释放才能访问资源。
2. 信号量(Semaphore):信号量是一种用于控制同时访问某一资源的线程数目的方法。它可以允许多个线程同时访问资源,但是可以通过信号量的计数来控制同时访问的线程数量。
3. 条件变量(Condition Variable):条件变量用于在某些特定条件下使线程等待或唤醒。它通常与互斥锁一起使用,以实现在满足特定条件时线程的阻塞和唤醒。
4. 读写锁(Read-Write Lock):读写锁允许多个线程同时读取共享资源,但是在写操作时需要互斥锁来保护资源,以避免多个线程同时写入导致数据不一致性。
5. 原子操作(Atomic Operations):原子操作是一种不可分割的操作,能够保证在多线程环境下的执行不会被中断,从而避免竞争条件。
线程同步的目的是确保线程之间的协调和有序执行,以避免数据竞争和其他并发问题。选择合适的线程同步机制取决于具体的应用场景和需求。
1.互斥锁(Mutex):
PS:临界区同样存在计数机制,进入几次临界区,就要退出几次临界区
示例:
#include <iostream>
#include <windows.h>int g;CRITICAL_SECTION g_cs;//创建互斥锁DWORD WINAPI MyThreadProc (LPVOID lp){for(int i = 0; i < 100000000; i++){EnterCriticalSection(&g_cs); //进入临界区g++;LeaveCriticalSection(&g_cs); //离开临界区}return 0;
}int main(){InitializeCriticalSection(&g_cs);//初始化互斥锁HANDLE h = CreateThread(NULL, 0, MyThreadProc, NULL, 0, 0);for(int i = 0; i < 100000000; i++){EnterCriticalSection(&g_cs); //进入临界区g++;LeaveCriticalSection(&g_cs); //进入临界区}WaitForSingleObject(h, INFINITE);std::cout << g << std::endl;CloseHandle(h);DeleteCriticalSection(&g_cs);return 0;
}
结果:
需要注意的是,过多地使用互斥锁可能会导致性能问题,因为只有一个线程能够执行临界区代码,其他线程需要等待
未完待续……
相关文章:
线程间的同步、如何解决线程冲突与死锁
一、线程同步概念: 线程同步是指在多线程编程中,为了保证多个线程之间的数据访问和操作的有序性以及正确性,需要采取一些机制来协调它们的执行。在多线程环境下,由于线程之间是并发执行的,可能会出现竞争条件…...
8.4一日总结
1.远程仓库的提交方式(免密提交) a.ssh:隧道加密传输协议,一般用来登录远程服务器 b.使用 git clone 仓库名 配置(生成公私钥对) ssh-Keygen [-t rsa -C 邮箱地址] 通过执行上述命令,全程回车,就会在~/.ssh/id_rsa(私钥)和id_rsa.pub(公钥),私钥是必须要保存好的,并不能…...
【面试】某公司记录一次面试题
文章目录 框架类1. Spring boot与 spring 架相比,好在哪里?2. Spring boot以及 Spring MVC 常用注解(如requestingMapping,responseBody 等)3. 常用的java 设计模式,spring 中用到哪些设计模式4. SpringIOC是什么,如何理解5. AOP…...
215. 数组中的第K个最大元素(快排+大根堆+小根堆)
题目链接:力扣 解题思路: 方法一:基于快速排序 因为题目中只需要找到第k大的元素,而快速排序中,每一趟排序都可以确定一个最终元素的位置。 当使用快速排序对数组进行降序排序时,那么如果有一趟排序过程…...
Ubuntu18.04配置ZED_SDK 4.0, 安装Nvidia显卡驱动、cuda12.1
卸载错误的显卡驱动、cuda 首先卸载nvidia相关的、卸载cuda sudo apt-get purge nvidia* sudo apt-get autoremove sudo apt-get remove --auto remove nvidia-cuda-toolkit sudo apt-get purge nvidia-cuda-toolkit 官方卸载cuda的方法: sudo apt-get --purge re…...
张量Tensor 深度学习
1 张量的定义 张量tensor理论是数学的一个分支学科,在力学中有重要的应用。张量这一术语源于力学,最初是用来表示弹性介质中各点应力状态的,后来张量理论发展成为力学和物理学的一个有力数学工具。 张量(Tensor)是一个…...
用Rust实现23种设计模式之桥接模式
桥接模式的优点: 桥接模式的设计目标是将抽象部分和实现部分分离,使它们可以独立变化。这种分离有以下几个优点: 解耦和灵活性:桥接模式可以将抽象部分和实现部分解耦,使它们可以独立地变化。这样,对于抽象…...
扩散模型实战(一):基本原理介绍
扩散模型(Diffusion Model)是⼀类⼗分先进的基于物理热⼒学中的扩散思想的深度学习⽣成模型,主要包括前向扩散和反向扩散两个过程。⽣成模型除了扩散模型之外,还有出现较早的VAE(Variational Auto-Encoder,…...
解决npm ERR! code ERESOLVE -npm ERR! ERESOLVE could not resolve
当使用一份vue源码开发项目时,npm install 报错了 npm ERR! code ERESOLVEnpm ERR! ERESOLVE could not resolvenpm ERR!npm ERR! While resolving: vue-admin-template4.4.0npm ERR! Found: webpack4.46.0npm ERR! node_modules/webpacknpm ERR! webpack"^4.0…...
HttpServletRequest和HttpServletResponse的获取与使用
相关笔记:【JavaWeb之Servlet】 文章目录 1、Servlet复习2、HttpServletRequest的使用3、HttpServletResponse的使用4、获取HttpServletRequest和HttpServletResponse 1、Servlet复习 Servlet是JavaWeb的三大组件之一: ServletFilter 过滤器Listener 监…...
css在线代码生成器
这里收集了许多有意思的css效果在线代码生成器适合每一位前端开发者 布局,效果类: 网格生成器https://cssgrid-generator.netlify.app/ CSS Grid Generator可帮助开发人员使用CSS Grid创建复杂的网格布局。网格布局是创建Web页面的灵活和响应式设计的强…...
在java中如何使用openOffice进行格式转换,word,excel,ppt,pdf互相转换
1.首先需要下载并安装openOffice,下载地址为: Apache OpenOffice download | SourceForge.net 2.安装后,可以测试下是否可用; 3.build.gradle中引入依赖: implementation group: com.artofsolving, name: jodconverter, version:…...
手机变电脑2023之虚拟电脑droidvm
手机这么大的内存,装个app来模拟linux,还是没问题的。 app 装好后,手指点几下确定按钮,等几分钟就能把linux桌面环境安装好。 不需要敲指令, 不需要对手机刷机, 不需要特殊权限, 不需要找驱…...
HDFS中的sequence file
sequence file序列化文件 介绍优缺点格式未压缩格式基于record压缩格式基于block压缩格式 介绍 sequence file是hadoop提供的一种二进制文件存储格式一条数据称之为record(记录),底层直接以<key, value>键值对形式序列化到文件中 优…...
【MySQL】检索数据使用数据处理函数
函数 与其他大多数计算机语言一样,SQL支持利用函数来处理数据。函数一般是在数据上执行的,它给数据的转换和处理提供了方便。 函数没有SQL的可移植性强:能运行在多个系统上的代码称为可移植的。多数SQL语句是可移植的,而函数的可…...
【嵌入式学习笔记】嵌入式入门6——定时器TIMER
1.定时器概述 1.1.软件定时原理 使用纯软件(CPU死等)的方式实现定时(延时)功能有诸多缺点,如CPU死等、延时不精准。 void delay_us(uint32_t us) {us * 72;while(us--); }1.2.定时器定时原理 使用精准的时基&#…...
GD32F103输入捕获
GD32F103输入捕获程序,经过多次测试,终于完成了。本程序将TIMER2_CH2通道映射到PB0引脚,捕获PB0引脚低电平脉冲时间宽度。PB0是一个按钮,第1次按下采集一个值保存到TIMER2_CountValue1中,第2次按下采集一个值保存到TIM…...
[RT-Thread]基于ARTPI的文件系统认识与搭建
[写作为了记忆,个人最终输出的内容往往是遗忘后最容易捡起的内容,故以此作文] 目录 [写作为了记忆,个人最终输出的内容往往是遗忘后最容易捡起的内容,故以此作文] 前提 内容 认识 基于ARTPI的文件系统的挂载 ROMFS与LFS. (默认自动挂载,romfs可读不可写) 搭…...
动态规划+二分查找
题目描述:给定一个区间数组,[[1,2,3],[3,4,2],[2,4,4]],每个区间有价值,求在获取k个区间的条件下面,求获得的最大的价值,关键是dp的定义和二分查找的写法(小于tar额最右下标) import…...
8.2小非农ADP数据来袭黄金将会如何表现?
近期有哪些消息面影响黄金走势?黄金多空该如何研判? 黄金消息面解析: 周二(8月1日)现货黄金价格回落,原因是美元指数升创7月10日以来新高至102.43.美联储官员乐观言论夯实美国经济软着陆预期。此外,中国刺激措施将…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
