互斥的学习

深度学习500问阅读笔记——理解One Hot Encodeing原理及作用? 这是深度学习500问系列笔记之一,帮助我深入记忆知识,如有不足,随时欢迎交流和探讨。 11.理解One Hot Encodeing原理及作用? 问题由来 在很多机器学习任务中,特征并不总是连续值,而有可能是分类值。 例如,考虑以下的三个特征: ["male","female"] ["from Europe","from US","from Asia"] ["use Firefox","uses Chrome","uses Safari","uses Internet Explorer"] 如 阅读详情
#include <iostream>
#include <mutex>
#include <memory>
#include <utility>
#include <stack>

template<class T>
class threadsafe_stack {
private:
	std::stack<T> data;
	mutable std::mutex m;

public:
	threadsafe_stack(){}
	threadsafe_stack(const threadsafe_stack& other) {
		std::lock_guard<std::mutex> lock(other.m);
		data = other.data;
	}
	threadsafe_stack& operator=(const threadsafe_stack&) = delete;

	void push(T val) {
		std::lock_guard<std::mutex> lock(m);
		data.push(std::move(val));
	}

	std::shared_ptr<T> pop() {
		std::lock_guard<std::mutex> lock(m);
		if (data.empty()) {
			return nullptr;
		}
		std::shared_ptr<T> const res(std::make_shared<T>(std::move(data.top())));
		data.pop();
		return res;
	}

	bool pop(T& val) {
		std::lock_guard<std::mutex> lock(m);
		if (data.empty()) {
			return false;
		}
		val = std::move(data.top());
		data.pop();
		return true;
	}

	bool empty() const {
		std::lock_guard<std::mutex> lock(m);
		return data.empty();
	}
};

一、互斥视角下:出栈返回智能指针的核心原因

1. 核心目标:保证互斥锁保护范围内的 “异常安全”

互斥锁的核心是保证 “共享资源操作的原子性”,但仅加锁还不够 —— 需确保锁作用域内的操作即使抛异常,共享资源(栈)的状态也不会被破坏,智能指针是实现这一目标的最优解:

(1)问题根源:直接返回值的异常风险(破坏原子性)

若在互斥锁内直接返回值,流程如下:

// 危险设计:锁内直接返回值
T pop() {
    std::lock_guard<std::mutex> lock(m); // 加锁(保证原子性)
    T temp = data.top(); // 步骤1:拷贝栈顶值(可能抛异常)
    data.pop();          // 步骤2:修改共享资源(出栈)
    return temp;         // 步骤3:返回值(可能抛异常)
}
  • 风险:步骤 1/3 若因内存不足、自定义类型拷贝构造抛异常,步骤 2 已执行(栈顶元素被移除),但值未传递给调用者,共享资源状态与数据不一致,互斥锁的原子性保障失去意义;
  • 本质:修改共享资源(data.pop())的操作,不能放在 “可能抛异常的拷贝 / 返回” 之前。
(2)智能指针的解决方案:先安全拷贝,再修改共享资源
std::shared_ptr<T> pop() {
    std::lock_guard<std::mutex> lock(m); // 加锁(原子性基础)
    if (data.empty()) return nullptr;    // 空判断(下文详解)
    // 步骤1:堆上创建智能指针(拷贝/移动值,若抛异常,栈未修改)
    std::shared_ptr<T> const res(std::make_shared<T>(std::move(data.top())));
    // 步骤2:仅当拷贝成功,才修改共享资源(原子性+异常安全)
    data.pop();
    return res;
}
  • 核心逻辑:互斥锁保证 “判空→创建智能指针→出栈” 全程原子化,而智能指针将 “拷贝值” 提前到 “修改栈” 之前 —— 即使拷贝抛异常,栈的状态不变,彻底避免数据丢失;
  • 额外优势:智能指针自动管理堆内存,无需手动释放,避免裸指针在多线程下的悬空 / 泄漏问题。

2. 互斥锁与智能指针的配合原则

  • 互斥锁保证 “操作流程的原子性”(不被其他线程打断);
  • 智能指针保证 “原子流程内的异常安全”(流程不被异常打断);
  • 二者结合,才是真正的 “线程安全 + 异常安全”。

二、互斥视角下:空判断的核心规则

1. 空判断必须在互斥锁内(原子性的关键)

(1)错误做法:锁外判空,破坏原子性
// 致命错误:判空和出栈拆分为两个锁区域
if (!stack.empty()) { // 锁1:判空后解锁,间隙出现
    stack.pop();      // 锁2:出栈前加锁,可能已空
}
  • 问题:两次加锁之间有 “解锁→其他线程入 / 出栈→再加锁” 的间隙,即使互斥锁本身是安全的,组合操作也失去原子性,可能导致空栈出栈崩溃;
  • 本质:互斥锁的原子性必须覆盖 “判空 + 出栈” 的完整业务逻辑,而非单个操作。
(2)正确做法:锁内判空,保证原子性
std::shared_ptr<T> pop() {
    std::lock_guard<std::mutex> lock(m); // 加锁,原子化区域开始
    if (data.empty()) return nullptr;    // 锁内判空,无间隙
    // 出栈逻辑...
}

bool pop(T& val) {
    std::lock_guard<std::mutex> lock(m); // 加锁,原子化区域开始
    if (data.empty()) return false;      // 锁内判空,无间隙
    // 出栈逻辑...
}
  • 核心:互斥锁从函数开始就持有,“判空→出栈” 全程在锁内,其他线程无法在中间插入操作,保证组合逻辑的原子性;
  • 空判断的返回值(nullptr/false):替代抛异常,让调用者无需捕获异常,同时不破坏锁内原子性。

2. 空判断的额外作用:异常安全兜底

  • 锁内判空是 “最后一道防线”:即使调用者违规先调用empty()再调用pop(),锁内的空判断仍能避免空栈出栈的非法操作;
  • 判空后直接返回:不执行后续的data.top()/data.pop(),避免访问空栈的未定义行为,保证共享资源操作的合法性。

核心总结

  1. 返回智能指针的核心:在互斥锁保证原子性的基础上,解决 “拷贝 / 返回抛异常导致共享资源状态破坏” 的问题,是原子性 + 异常安全的双重保障;
  2. 锁内空判断的核心:保证 “判空 + 出栈” 的完整逻辑在互斥锁作用域内,消除间隙,避免原子性失效,同时兜底空栈操作的合法性;
  3. 互斥锁的关键:不仅要保护单个操作,更要保护 “检查 + 操作” 的完整业务逻辑,智能指针和锁内判空都是这一原则的具体体现。
HBuilderx连接微信开发者工具 系列文章目录 文章目录系列文章目录前言一、环境1.HBuilerx 工具2.微信开发者工具二、关联微信开发者工具1.HBuilderx新建项目2.关联微信开发者工具3.运行微信小程序出现异常解决方法3.最终效果总结 前言 使用HBuilderx工具关联微信开发者工具,进行小程序开发 提示:以下是本篇文章正文内容,下面案例可供参考 一、环境 1.HBuilerx 工具 HBuilderx 2.微信开发者工具 微信开发者工具 二、关联微信开发者工具 1.HBuilderx新建项目 2.关联微信开发者工具 阅读详情

相关推荐

零信任架构实战:“持续验证+动态授权”全流程解析(附策略引擎联动图)

《零信任实战指南:7图拆解核心流程与行业案例》摘要:本文通过7张架构图系统解析零信任五大核心流程:强身份认证、设备检查、动态授权、持续监控和自动降权。对比金融(重数据审计)与制造业(重物理绑定)的落地差异,指出三大常见误区及解决方案。数据显示,零信任可使安全响应提速60%,泄露成本降低45%。文章提供6个月实施路线图,强调零信任是"智能信任"体系,建议企业分阶段改造,优先保护核心系统。附赠金融/制造行业策略模板及甘特图示例。(149字)

sara_han的博客 773

进程互斥的软件实现方法【操作系统学习笔记】

每个进程在进入临界区之前先检查当前有没有别的进程想进入临界区,如果没有,则把自身对应的标志 flag[i] 设为 true ,之后开始访问临界区。在退出区把临界区的使用权转交给另一个进程(相当于在退出区既给另一个进程“解锁”,又给自己"上锁")主要问题:不遵循“空闲让进,有限等待”原则,可能导致“饥饿”主要问题:不遵循“忙则等待”的原则。“检查”,退出区“解锁”(先加锁)主要问题:不遵循“空闲让进”原则。“上锁”,退出区“解锁”

Mikey99的博客 342

信号完整性之阻抗(五)

一、什么是阻抗 阻抗的概念是从高中或者初中大家可能就会接触到,没想它一直陪伴我十年了。在我的印象中,提到阻抗我可能就会想到电阻,这样的思想局限也限制了我平常思考问题。所以今天也想把阻抗这个概念在顺理一遍,有错误或者欠缺的地方希望大家指正。 1.什么是阻抗: ==在具有电阻、电感和电容的电路里,对电路中的电流所起的阻碍作用叫做阻抗。阻抗常用Z表示,是一个复数,实部称为电阻,虚部称为电抗,其中电容在电路中对交流电所起的阻碍作用称为容抗 ,电感在电路中对交流电所起的阻碍作用称为感抗,电容和电感在电路中对交流电引

刘小同学的博客 2587

吃字母------线程同步与互斥的学习

线程的同步与互斥的实战----吃字母 希望能给你一些启发: 我们在资源输入数据,下面的两个缓冲区,通过线程获取资源的数据,吃货A-D 抢 两个缓冲区的数据 并放入对应的数据栏中。 例如: 解决思想和方案: 缓冲区的数据通过一个线程去资源栏中获取,这一个线程与下面4个吃货的线程是同步的关系, 下面4个线程是互斥的。 下面是代码: // 9_2实战_吃字母.cpp : Defines the entry point for the application. // 下面展示一些 内联代码片。 // A cod

weixin_41020820的博客 300

SecureCRT串口连接保姆级教程:从驱动安装到波特率设置(附常见问题解决)

本文提供SecureCRT串口连接的保姆级教程,涵盖从USB转串口驱动安装、端口识别到波特率等核心参数设置的完整流程。针对连接失败、乱码、键盘输入无响应等高频问题,给出了深度排查与解决方案,帮助网络与嵌入式开发新手快速掌握串口调试技能。

weixin_29281941的博客 433

FFmpeg入门详解之110:RTSP协议讲解

TCP/IP 协议体系中的一个应用层协议,该协议定义了一对多应用程序如何有效地通过 IP 网络传送多媒体数据。RTSP在体系结构上位于RTP和RTCP之上,它使用TCP或UDP完成数据传输。HTTP与RTSP相比,HTTP传送HTML,而RTSP传送的是多媒体数据。正在上传…重新上传取消RTSP是基于文本的协议,采用ISO10646字符集,使用UTF-8编码方案。行以CRLF中断(\r\n:10,13:0x0A,0x0D),包括消息类型、消息头、消息体和消息长。

福优学苑@音视频+流媒体 2529

FreeRTOS内部机制学习笔记三——互斥的引入

FreeRTOS内部机制学习笔记三——互斥的引入 在多任务系统中,如果有两个或者多个任务需要使用同一个变量,那么会出现一些数据错误。 ​ 比如任务A和任务B都需要实现对某个全局变量的自加,而变量自加需要三个过程:①从内存读取数据②对数据进行自加一③向内存写入数据。如果任务A在执行完过程①后被切换带任务B,任务B会对变量值进行修改,当时间片再次分配给任务A时,任务A会继续执行上次中断在过程①的任务,当执行完过程③之后,将数据写入内存中,这时上次任务B对全局变量的数据操作将不会起作用,因为被这次操作将上次任务B

qq_46384359的博客 818

【已解决】飞牛nas(fnOS)异常断电导致硬盘未挂载(无法挂载),系统内部错误修复、救回数据全流程!(含更新系统后外接 NTFS 格式硬盘丢失的修复方法)

fnOS 飞牛NAS遭遇非正常断电后,存储空间显示「未挂载」或更新系统后外接 NTFS 格式硬盘丢失,点击挂载提示「系统内部错误」!💥 博主已经完美恢复,本文记录了相关的解决方案,帮您恢复或最大程度保住重要数据🎉

XiaoqiangClub的博客 2196

进程互斥的硬件实现方式【操作系统学习笔记】

old记录是否已被上锁;再将lock设置为true;检查临界区是否已被上锁(若已上锁,则循环重复前几步)缺点:不满足“让权等待”,会导致“忙等”,执行的过程不允许被中断,只能一气呵成。,执行的过程不允许被中断,只能一气呵成。适用于多处理机环境;逻辑上等同于TSL指令。优点和缺点同TSL指令。

Mikey99的博客 628

国科大学习资料--计算机网络--历年考题1

国科大学习资料–计算机网络–历年考题1 1、假定有一个通信协议,每个分组都引入100字节的开销用于头和成帧,现在使用这个协议发送1M字节的数据(为方便计算,1M=10^6),然而在传递的过程中有一个字节被破坏了,因而包含该字节的那个分组被丢弃并重传。(1)当数据的分组大小为1000、5000、20000和40000字节时,计算相应(包括开销)的传递字节总数目。(2)计算分组大小的最优值是多少,即分组的大小为何值时总的传输字节数最少。(提示:最优值不是1000、5000、20000和40000字节中的一个)

无名何许人的博客 1181

Windows远程桌面开发之九-虚拟显示器(Windows 10 Indirect Display 虚拟显示器驱动开发)

by fanxiushu 2019-06-24 转载或引用请注明原始作者。 这里与远程桌面关系不是太大,但这个部分是xdisp_virt远程控制程序的实现多显示器桌面扩展的子功能,因此也归为远程桌面开发一类。 这篇文章与之前发布的...

fanxiushu的专栏 2万+

【学习笔记】第二章——进程同步、进程互斥、进程互斥的硬件/软件实现方法

文章目录一. 进程同步 && 进程互斥四个区域四个原则总结:二. 进程互斥的软件实现方法1)单标志法2)双标志先检查法3)双标志后检查法4)Peterson 算法总结三. 进程互斥的硬件实现方法1)中断屏蔽方法2)TestAndSet 指令3)Swap 指令总结 一. 进程同步 && 进程互斥 由于进程有异步性,因此需要有同步存在。 同步也叫直接制约关系,指为完成某任务而建的两或多个进程,需要在某些位置协调各自的工作次序而产生的制约关系。进程间的直接制约关系就是源于他们之

只能说希望每日一更 725

2024年数字IC秋招-格科微-数字电路设计工程师-笔试题

笔试题型:简答题(9个)笔试平台:牛客(电脑监控)笔试时间:2h。

qq_42135020的博客 1605

黑马程序员 日记二:线程的互斥的学习

---------------------- android培训、java培训、期待与您交流! ---------------------- 多个线程能够实现互斥与同步的关键,在于synchronized这个关键字。通过视频的讲解,可以知道,synchronized使用,可以分为以下几种情况: 1.方法内部分代码的互斥; 2.实现整个方法的互斥; 3.synchronized与st

boybeak的专栏 695

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

操作系统学习笔记02【进程控制——进程互斥的硬件实现方法】【自用】

什么是进程控制? 如何实现进程控制: 为了避免把某一进程pbc从一个队列转移到另一个队列,但是并没有把pbc内的状态标志改为新的对应状态,从而导致pcb的状态标志与实际所处队列不一样这一情况发生,需要原语来实现进程控制。 当关中断指令被执行后,外部中断信号会被暂时地忽略掉,直到开中断指令被执行后,外部中断信号才会被得到执行。 进程控制相关原语: (1)创建原语 (2)撤销原语 异常结束:比如整数除0等bug 外界干预:用户主动请求撤销进程,如w...

n0ahmayberry的博客 3093

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

解锁Linux线程:同步与互斥的奥秘

线程同步,简单来说,就是协同步调多个线程的执行顺序 ,让它们按照预定的先后次序运行。就好比一场接力赛跑,每个线程是一位赛跑选手,接力棒就是共享资源。选手们必须按照顺序依次接过接力棒并完成自己的赛程,不能乱了次序。如果没有同步机制,线程们就可能像没有组织的选手一样,随意争抢接力棒,导致比赛混乱不堪,程序也会出现各种难以预料的错误。在多线程编程中,线程同步至关重要。当多个线程并发执行时,它们对共享资源的访问顺序变得难以预测。

大雨淅淅的博客 1199

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

操作系统学习小结(11.22,进程的同步与互斥,进程互斥的4种软件算法,3种硬件方法,信号量机制,信号量机制实现进程的互斥,前驱关系,同步)

同步也称为直接制约关系。 在多道程序环境下,进程是并发执行的,不同进程之间存在着不同的相互制约关系。为了协调进程之间的相互制约关系,如等待、传递信息等,引入了进程同步的概念。进程同步是为了解决进程的异步问题。 一个简单的例子来理解这个概念。 例如,让系统计算1 + 2x3,假设系统产生两个进程: 一个是加法进程,一个是乘法进程。要让计算结果是正确的,一定要让加法进程发生在乘法进程之后,但实际上操作系统具有异步性,若不加以制约,加法进程发生在乘法进程之前是绝对有可能的,因此要制

weixin_66455428的博客 1436

2.3.3 操作系统之实现临界区进程互斥的硬件实现方法

1 思维导图 2 中断隐藏方法 3 TestAndSet指令 执行TSL指令时,它的内部运转逻辑: 假设lock现在为false,代表临界资源A空闲,那么我就可以访问这个资源,同时将lock=true,提醒别的进程,这个临界资源A我正在使用,让他们等等 假设lock为true,代表临界资源正在有人使用,所以我必须等待,并且将lock=true,并不影响什么,所以没关系,只是为了让lock为false时可以上锁,将上锁与检查在一个TSL指令完成。 4Swap指令 old是每个进程都要.

StudyWinter的博客 552

dpg learning 和q_深度学习和强化学习之间的差别有多大?

我是做深度强化学习的(Deep Reinforcement Learning)的,这个问题有趣。我对@张馨宇他在此问题下的简洁回答非常认同:“可以用深度学习这个工具来做强化学习这个任务,也可以不用”。以下是对他回答的一些补充:我奶奶也看得懂的简短回答(或者说这是目录):有深度神经网络的机器学习是深度学习估计未来的收益,并根据这些收益对当前动作进行强化的算法设计思想是强化学习直接讨论它们的差别并不合...

weixin_36193839的博客 619

FreeRTOS学习(二)

信号量代表某一类资源其值表示系统中该资源的数量。信号:起通知作用;量:还可以用来表示资源的数量信号量的值>0, 表示有资源可以用, 可以申请到资源,信号量的值=0, 表示没有资源可以用, 无法申请到资源, 阻塞.当"量"没有限制时,它就是"计数型信号量"(Counting Semaphores)当"量"只有 0、1 两个取值时,它就是"二进制信号量"(Binary Semaphores)支持的动作:"give"给出资源,计数值加 1;

学习过程记录,欢迎大家交流互动,互相学习 1187

【RTOS学习】事件组 | 任务通知

介绍了事件组的概念和原理,以及事件组的使用,包括基本使用和同步点。还讲解了任务通知的概念和原理,以及使用过程中的注意事项。

weixin_63726869的博客 1191

秒杀多线程第九篇 经典线程同步总结,关键段 事件 互斥量 信号量

前面《秒杀多线程第四篇一个经典的多线程同步问题》提出了一个经典的多线程同步互斥问题,这个问题包括了主线程与子线程的同步,子线程间的互斥,是一道非常经典的多线程同步互斥问题范例,后面分别用了四篇 《秒杀多线程第五篇经典线程同步关键段CS》 《秒杀多线程第六篇经典线程同步事件Event》 《秒杀多线程第七篇经典线程同步互斥量Mutex》 《秒杀多线程第八篇经典线程同步信号量Semaphore》

miao6664659的专栏 626

机器学习笔记

一般而言,训练样本越多,得到关于未知“分布”的信息越多,就越有可能通过学习获得具有强泛化能力的模型。训练样本构成训练集,测试样本构成测试集。不改变初始数据集D的样本,每次从中随机拷贝得到采样数据集D',D'用作训练集,D/D'用作测试集。通过分层采样,将数据集划分为两个互斥集合,一般采用若干次随机划分、重复进行实验评估后取平均值作为留出法的评估结果,划分比例大约是2/3~4/5样本用于训练,剩余样本用于测试。本质上是进行多次留出法,且每次都换不同的子集作为测试集,最终让所有样本均至少成为一次测试样本。

2401_86112570的博客 505

【深度学习】Cross Entropy Loss

文章目录起因Cross Entropy Loss的由来Tensorflow中的CEPytorch中的CEPytorch中CE和BCE的区别Pytorch对真正CE的支持 Cross Entropy Loss (CE)被经常用在分类问题中,但之前也没仔细了解过其中一些细节。本博客主要针对Pytorch中对CE的支持,但也结合了对TensorFlow中的CE的支持。 其中本博客参考总结了大量其他博客的...

麒麒哈尔的博客 6384

FreeRTOS 学习笔记:同步互斥与通信

第六天深入学习 FreeRTOS 同步互斥与通信,解析 volatile 作用、环形缓冲区原理,梳理队列 / 信号量 / 互斥量关系,优化任务调度与数据传输,解决变量操作冲突问题 。

weixin_45198947的博客 1305

学习攻略 | 如何才能学好并发编程?

并发编程并不是一门相对独立的学科,而是一个综合学科。并发编程相关的概念和技术看上非常零散,相关度也很低,总给你一种这样的感觉:我已经学习很多相关技术了,可还是搞不定并发编程。那如何才能学习好并发编程呢?其实很简单,只要你能从两个方面突破一下就可以了。一个是“跳出来,看全景”,另一个是“钻进去,看本质”。跳出来,看全景我们先说“跳出来”。你应该也知道,学习最忌讳的就是“盲人摸象”,只看到局部,而没有...

优快云学习 294
上一篇: 网络通信中涉及结构体作为数据包进行传输要注意取消内存对齐
CodeDingHai
博客等级 码龄1年 47粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值