Other

面试官:请用SQL模拟一个死锁

文章首发于公众号:BiggerBoy 有读者说面试被问到怎么用SQL模拟数据库死锁? 这位读者表示对Java中的死锁还是略知一二的,但是突然用SQL写死锁的案例之前还真没遇到过,这个问题没答上来。所以今天就带大家一起来看下怎么用SQL让数据库中产生死锁。 什么是死锁 说到死锁,还是先来复习下什么是死锁吧。 死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。 数据库死锁是指两个资源互相等待,如果需要“修改”一条数据,首先数据库管理系统会在上面加锁,以保证在同一时间只有一个事务能进行修改操作。锁定(Locking)发生在当一个事务获得对某一资源的“锁”时,这时,其他的事务就不能更改这个资源了,这种机制的存在是为了保证数据一致性。 数据库死锁示例 好了,复习完回到今天的正题。 有如下两个事务: 事务1先执行SQL1,更新id=1的,然后执行SQL2,更新id=2的。 事务2恰恰相反,它先更新id=2的,再更新id=1的。 SQL代码如下: -- 事务1 begin; -- SQL1更新id为1的 update user set age = 1 where id = 1; -- SQL2更新id为2的 update user set age = 2 where id = 2; commit; -- 事务2 begin; -- SQL1更新id为2的 update user set age = 3 where id = 2; -- SQL2更新id为1的 update user set age = 4 where id = 1; commit; 我们怎么手动操作模拟一下呢?

2022深读《嵌入式Linux内存使用与性能优化》笔记

尊重原创版权: https://www.gewuweb.com/hot/10176.html 《嵌入式Linux内存使用与性能优化》笔记 尊重原创版权: https://www.gewuweb.com/sitemap.html 这本书有两个关切点:系统内存(用户层)和性能优化。 这本书和Brendan Gregg的《Systems Performance》相比,无论是技术层次还是更高的理论都有较大差距。但是这不影响,快速花点时间简单过一遍。 然后在对《Systems Performance》进行详细的学习。 由于Ubuntu测试验证更合适,所以在Ubuntu(16.04)+Kernel(4.10.0)环境下做了下面的实验。 全书共9章:14章着重于内存的使用,尽量降低进程的内存使用量,定位和发现内存泄露;59章着重于如何让系统性能优化,提高执行速度。 第1章 内存的测量 第2章 进程内存优化 第3章 系统内存优化 第4章 内存泄露 第5章 性能优化的流程 第6章 进程启动速度 第7章 性能优化的方法 第8章 代码优化的境界 第9章 系统性能优化 用户空间的内存使用量是由进程使用量累积和系统使用之和,所以优化系统内存使用,就是逐个攻克每个进程的使用量和优化系统内存使用。。 俗话说“知己知彼,百战不殆”,要优化一个进程的使用量,首先得使用工具去评估内存使用量( 第1章 内存的测量 ); 然后就来看看进程那些部分耗费内存,并针对性进行优化( 第2章 进程内存优化 ); 最后从系统层面寻找方法进行优化( 第3章 系统内存优化 )。 内存的使用一个致命点就是内存泄露,如何发现内存泄露,并且将内存泄露定位是重点( 第4章 内存泄露 ) 第1章 内存的测量 关于系统内存使用,将按照 (1)明确目标 -> (2) 寻找评估方法, (3)了解当前状况->对系统内存进行优化->重新测量 ,评估改善状况的过程,来阐述系统的内存使用与优化。 (1)明确目标,针对系统内存优化,有两个: A. 每个守护进程使用的内存尽可能少 B. 长时间运行后,守护进程内存仍然保持较低使用量,没有内存泄露 。 (2)寻找评估方法,第1章关注点。 (3)对系统内存进行优化,第2章针对进程进行优化,第3章针对系统层面进行内存优化,第4章关注内存泄露。 系统内存测量 free用以获得当前系统内存使用情况。

2022 Java生态系统报告:Java 11超Java 8、Oracle在缩水、Amazon在崛起!

近日,New Relic发布了最新的2022 Java生态系统报告,这份报告可以帮助我们深入的了解Java体系的最新使用情况,下面就一起来看看2022年,Java发展的怎么样了,还是Java 8 YYDS吗? Java 11成为新的标准 在2020年的时候,Java 11已经推出了1年多,但当时Java 8的占有率高达84.48%。2年过去了,Java 11上生产的比例第一次超过Java 8,占有率已经达到了48.44%。曾今的霸主Java 8几乎跌掉了一半,以46.45%占据第二。 而大势所趋的、整个Java生态都在拥抱的Java 17在排行榜上还是处于比较低的位置。这个其实还是意料之中的,因为生态的支持还需要一定时间的演进,比如Spring这个Java生态的大基座,对于Java 17的重要支持还要等到今年年底的Spring Boot 3发布(对这部分感兴趣的小伙伴记得关注我,公众号程序猿DD,长期分享这块最前沿的专业解读),同时周边的其他各种框架、中间件也都要全面更上之后,才真正具备上生产的成熟度。 所以,先从Java 8到Java 11,还是一个不错的选择,小步快跑,免得到时候直接从Java 8到Java 17,步子太大,扯到x就不好了... 我正在连载Java 8之后的新特性解读,这次一改之前的博客风格,采用文档(https://www.didispace.com/java-features/)+ 视频(B站、视频号)的方式编写,阅读与学习体验更加。感兴趣的小伙可以关注收藏起来,能转发分享下那是更好,这样更有更新的动力。 最流行的非LTS版本:Java 14 从Java 9开始,Java版本的发布模式发生了变化。每隔6个月就会有一个新版本发布,但这些版本只在下一个版本之前受到官方支持。这样做的目的是让新功能更频繁可用。 但是,与生产中的LTS版本相比,这些临时的非LTS版本使用率一直都非常低,只有2.7%的应用程序在使用。 虽然像Azul Systems这样的一些供应商在一些非LTS版本上提供了补丁,但大多数的供应商没有这么做。这可能是为什么大家不愿意使用的原因。在非LTS Java版本中,Java 14最受欢迎。 Oracle在缩水,Amazon在崛起 这次的报告中,值得关注的是JDK发行版的变化。虽然大部分开发人员还是会从Oracle获得JDK,而OpenJDK项目中的开源内容已经产生了丰富的选择。 上图显示了Oracle在对其JDK 11发行版进行更严格的许可证控制之后(在使用Java 17返回到更开放的立场之前)的变化。2020年的时候,Oracle以绝对优势(约占Java市场的75%)成为最受欢迎的供应商。2年过去了,虽然他们依然还是头把交椅,但他们的份额已经减少了一半。而Amazon的市场占有率从2020年的2.18%大幅攀升至22%。 从2021年11月以来,还有一些有趣的变化:在Java 17发布之前,Eclipse Adoptium和Amazon在这份榜单上几乎处于完全相反的位置。 容器中的资源分配 计算资源的配置 容器会影响人们分配计算和内存资源的方式。这份报告中的数据显示,在容器中运行的应用程序中,少于四个核心的应用程序所占的比例要高得多。 在人们经常部署容器的云环境中,小规模运行的驱动力很有意义。但这一趋势可能会给一些应用程序带来意想不到的问题。比如:当运行的内核少于2个时,在最近JVM上使用默认的G1垃圾收集器所带来的许多并发好处就消失了。所有这些单核实例可能都在使用串行收集器,并为此付出了性能代价,但许多人可能甚至不知道这一点。 内存资源的配置 在比较内存设置时,也会出现类似的趋势,它们倾向于给容器中的实例分配更小的内存。 该报告中显示,只有大约80%的容器化应用程序通过-XMX或-XX:MaxRAMPercentage标志显式请求JVM内存上限。从Java 9开始,JVM中的容器感知功能意味着这可能不会像过去那样对这些应用程序造成安全问题,只要JVM是每个容器中运行的唯一进程。 最常用的垃圾收集算法 垃圾收集(GC)算法在JVM性能中起到核心作用,所以这块一直以来都是社区讨论最多的话题。新的数据显示,在Java 8之后,垃圾收集器的使用发生了明显的变化。 G1的总体受欢迎程度非常高。考虑到Java 11和更高版本上的G1收集器具有更新的默认设置和更高的性能,所以这一结果这并不令人惊讶。 原始报告我放到公众号里了,对细节内容感兴趣的话,可以在公众号中发送关键词:relic-java-2022,获取完整报告。 好了,今天的分析那个就到这里!如果您学习过程中如遇困难?可以加入我们超高质量的Spring技术交流群,参与交流与讨论,更好的学习与进步! 欢迎关注我的公众号:程序猿DD。第一时间了解前沿行业消息、分享深度技术干货、获取优质学习资源

《Streaming Systems》第三章: Watermarks

定义 对于一个处理无界数据流的 pipeline 而言,非常需要一个衡量数据完整度的指标,用于标识什么时候属于某个窗口的数据都已到齐,窗口可以执行聚合运算并放心清理,我们暂且就给它起名叫 watermark 吧。 可以把系统当前处理时间当做 watermark 吗?显然不可以。第一章 已经讨论过,处理时间和事件时间的偏差是不确定的,根据处理时间无法对事件时间的进度进行准确衡量。 pipeline 的数据处理速率可以当做 watermark 吗?也不可以。pipeline 的数据处理速率不是一成不变的,会受到诸多因素的影响,也不能辅助判别数据的完整性。 那选择什么作为 watermark 合适呢,从头捋捋吧。我们假设每个事件都携带一个事件时间戳,我们分析一下 pipeline 中的事件时间分布情况。pipeline 上游对接输入,输入管道中都是等待处理的数据,处理完成后将结果发往下游的输出。如 图 3-1 所示,我们将已经接收但是未被处理的数据标记为红色,将处理完成的数据标记为蓝色,pipeline 中会同时存在等待处理和已经处理的数据。随着时间的推移,越来越多的数据会加入到 “红色” 区域中等待处理,当然也有越来越多的数据被处理完成,从 “红色” 区域移入到 “蓝色” 区域。 图中右侧黄色指针表示当前时间,左侧黄色指针追踪的是红色区域的最左侧,即 最早的那个未被处理数据的事件时间。我们就用这个值定义 watermark。 用这个值定义 watermark 能满足我们的最初要求: 完整性 如果 watermark 已经超过了某个时间戳 T,由于其单调性,不会再对 T 之前的事件进行处理(迟到数据除外)。因此,我们可以正确地处理 T 之前的窗口聚合。 可视性 如果一条消息由于任何原因卡在我们的 pipeline 中,watermark 不能 advance。 此外,我们将能够找到阻止 watermark 继续推进的问题根源。 图 3-1. pipeline 中的数据分布 Source Watermark 的创建 为了创建 watermark,我们需要为进入 pipeline 的每个消息分配一个逻辑事件时间戳。第二章 已经讨论过,watermark 无外乎两种类型:完美型 watermark 和启发式 watermark。创建哪种类型的 watermark 取决于数据源的本质。

LeetCode 0086 Partition List

原题传送门 1. 题目描述 2. Solution 1 1、思路分析 新建两个头结点,left存放小于x的结点,right存放大于等于x的结点值。从head遍历原始链表,结点值小于x挂left,大于等于x挂right,遍历结束后把right挂到left后面。 2、代码实现 package Q0099.Q0086PartitionList; import DataStructure.ListNode; public class Solution { public ListNode partition(ListNode head, int x) { ListNode left = new ListNode(0); ListNode right = new ListNode(0); ListNode l = left; ListNode r = right; while (head != null) { if (head.val < x) { l.next = head; l = l.next; } else { r.next = head; r = r.next; } head = head.

hashcat笔记

hashcat的扫描模式: 0.字典破解,使用字典进行破解1.组合破解,使用多个字典进行破解3.掩码破解,使用掩码方式进行破解6.字典+掩码破解7.掩码+字典破解 掩码设置 掩码格式肉眼可见是什么意思,只是在使用掩码时候需要用问号?+掩码来表示一位值:八位数字:?d?d?d?d?d?d?d?d八位啥也不知:?a?a?a?a?a?a?a?a4-6位字母密码:–increment --increment-min 4 --increment-max 6 ?l?l?l?l?l?l?l?l前四位为小写字母,后面四位数字:?l?l?l?l?d?d?d?d前三个字符,中间为root,后三位未知:?a?a?aroot?a?a?a通过掩码方式可以根据已知信息进行组合,更能加快hash破解速度。 常用参数 -a 指定要使用的破解模式,其值参考后面对参数。“-a 0”字典攻击,“-a 1” 组合攻击;“-a 3”掩码攻击。-m 指定要破解的hash类型,如果不指定类型,则默认是MD5-o 指定破解成功后的hash及所对应的明文密码的存放位置,可以用它把破解成功的hash写到指定的文件中–force 忽略破解过程中的警告信息,跑单条hash可能需要加上此选项–show 显示已经破解的hash及该hash所对应的明文–increment 启用增量破解模式,你可以利用此模式让hashcat在指定的密码长度范围内执行破解过程–increment-min 密码最小长度,后面直接等于一个整数即可,配置increment模式一起使用–increment-max 密码最大长度,后面直接等于一个整数即可,配置increment模式一起使用–outfile-format 指定破解结果的输出格式id,默认是32.了解JohnTheRipperJohn the Ripper免费的开源软件,是一个快速的密码破解工具,用于在已知密文的情况下尝试破解出明文的破解密码软件。主要目的是破解不够牢固的Unix/Linux系统密码。此次试验只是使用zip2john.exe获取zip文件的hash。 使用zip2john.exe文件获取flag.zip的hash值 zip2john.exe flag.zipflag.zip:$zip2$*0*3*0*b7d87e422bf350b36e436796bbc14ae8*7294*12*0aab67010215f567093a82dfdd75214b23ec*fda948392ccba597113e*$/zip2$:::::flag.zip-flag.txt方便起见,我hash复制到文件中(中间没有回车,为了能看的更清楚,从中间加了个回车。) 3,使用hashcat,设置hash类型为winzip13600 (类型在hashcat的帮助文档中查找对应上就行。)破解模式为掩码模式 hashcat64.exe -a 3 -m 13600 $zip2$*0*3*0*b7d87e422bf350b36e436796bbc14ae8*7294*12*0aab67010215f567093a82dfdd75214b23ec*fda948392ccba597113e*$/zip2$ ?d?d?d?d?h?h?h 先进行破解,再进行–show输出密码。 搜索 复制

移动机器人杂谈

移动机器人杂谈 移动机器人分类 移动机器人是一种在复杂环境下工作的,具有自行组织、自主运行、自主规划的智能机器人,融合了计算机技术、信息技术、通信技术、微电子技术和机器人技术等。 移动机器人是自动执行工作的机器装置,是一种由传感器、遥控操作器和自动控制的移动载体组成的机器人系统,具有移动功能,在代替人从事危险、恶劣(如辐射、有毒等)环境下作业和人所不及的(如宇宙空间、水下等)环境作业方面,比一般机器人有更大的机动性、灵活性。 移动机器人是一种在复杂环境下工作的,具有自行组织、自主运行、自主规划的智能机器人,融合了计算机技术、信息技术、通信技术、微电子技术和机器人技术等。 移动机器人的研究始于60年代末期。斯坦福研究院(SRI)的Nils Nilssen 和Charles Rosen 等人,在1966年至1972年中研发出了取名Shakey的自主移动机器人。目的是研究应用人工智能技术,在复杂环境下机器人系统的自主推理、规划和控制。 移动机器人的分类方式 1、根据移动方式来分,可分为:轮式移动机器人、步行移动机器人(单腿式、双腿式和多腿式)、履带式移动机器人、爬行机器人、蠕动式机器人和游动式机器人等类型; 2、按工作环境来分,可分为:室内移动机器人和室外移动机器人; 3、按控制体系结构来分,可分为:功能式(水平式)结构机器人、行为式(垂直式)结构机器人和混合式机器人; 4、按功能和用途来分,可分为:医疗机器人、军用机器人、助残机器人、清洁机器人等; 智能移动机器人,是一个集环境感知、动态决策与规划、行为控制与执行等多功能于一体的综合系统。集中了传感器技术、信息处理、电子工程、计算机工程、自动化控制工程以及人工智能等多学科的研究成果,代表机电一体化的较高成就,是目前科学技术发展较活跃的领域之一。 随着机器人性能不断地完善,移动机器人的应用范围大为扩展,不仅在工业、农业、医疗、服务等行业中得到广泛的应用,在城市安全、国防和空间探测领域等有害与危险场合得到很好的应用。因此,移动机器人技术已经得到世界各国的普遍关注。 本文参考文献参考链接 https://mp.weixin.qq.com/s/84TXqraLobBLMAFps6ZOtw https://baijiahao.baidu.com/s?id=1719760406088534452&wfr=spider&for=pc https://mp.weixin.qq.com/s/SzCwEBE4PR8Wmg5M5LlA8Q https://mp.weixin.qq.com/s/lbJVcwqS-UeyyLjlRg75AA https://mp.weixin.qq.com/s/NFMOd9B8L0f3ajUl-bUZ4g https://mp.weixin.qq.com/s/lsIuIdUYq-Vf_yWxByaXfA https://mp.weixin.qq.com/s/GmxqQUBu-adeOCkamkA5UA https://mp.weixin.qq.com/s/k2zPvU_3b9zlWYSYQauKsg https://mp.weixin.qq.com/s/OeWc_cctEkHXJYwMnd_tUA https://www.gkzhan.com/news/detail/134758.html 移动机器人主要需要解决定位、规划、控制等问题,目前重点的研究领域包括环境感知与建模、定位与导航、环境理解、多机器人协调等,未来移动机器人将朝着以下趋势发展: 1“自然导航+自主路径规划”成为主流 移动机器人发展经历了有轨方式(如磁带牵引方式)、信标方式(如二维码)、无信标方式(如SLAM,即时定位与地图构建)的不同阶段。SLAM技术可以让机器人在无信标的情况下也能实现定位导航,具有易部署、柔性等特点,更加适合在运行环境复杂、业务经常变动的场景下应用,因此受到越来越多客户青睐,正在成为业界主流趋势。 行业发展显示,导航技术的发展使设备从“车”逐渐过渡到“机器人”。随着新技术的发展,AGV自主化、智能化的程度越来越高,AMR的演进更是广泛扩大了行业的应用。 现阶段,尚没有任何一种能够“包打天下”的导航方式,只能根据应用的特点来选取最适合的导航方式,不同应用对导航的要求并不一样。在各种导航方式中,目前最受欢迎的是激光、视觉等不依赖人工环境的自然导航方式。 应用的多样性决定了技术发展方向的多元化,衡量技术优劣的标准依应用需求不同而不同,很难用统一的标准来衡量各种不同的技术。   2 深度学习将广泛应用,加强机器人对周围环境的理解 AI中的深度学习技术在计算机视觉中的应用主要有物体识别、目标检测与跟踪、语义分割、实例分割等,语义SLAM能把物体识别与视觉SLAM结合起来,将标签信息引入优化过程中,构建带物体标签的地图,实现机器人对周围环境内容的理解。 传统的2D障碍物检测存在许多局限性,通过人工智能语义分割,可以更有效地判断人或障碍物的情况,提高绕行效率,机器人系统可以提升应用效率和智能化水平。 新技术与机器人技术的加速融合将进一步推动产品的更新换代。移动机器人的自主性主要体现在“状态感知”、“实时决策”、“准确执行”这三个方面。物联网、AI、5G等新一代信息技术与机器人技术相互结合,能够让设备高效交互,数据更加自由流动,并通过算法指挥硬件发挥最大效能。   3 规模化集群作业成必然,更高效的多机协作方式成趋势 机器人在实际应用中,通常是以集群的方式协同完成特定的任务。如:月台的托盘搬运集货,原材料的料箱存储和拣选,产线之间的物料搬运;托盘可以使用无人叉车搬运,原材料的存储拣选可以使用二维码类KIVA机器人,产线之间物料搬运可以使用SLAM机器人。 一旦达到几百台甚至上千台机器人时,简单的逻辑思考已经不能解决问题,整个群体协作的效率无法得到有效保证。这时候就需要机器人能够不断学习、不断修正自身策略,AI将在其中扮演重要角色,让整个系统不断优化,群体智能化程度越来越高。 当移动机器人系统规模扩大,传统的管理调度系统正面临越来越苛刻的要求。移动机器人管理系统需要对具有避障绕行能力的AMR进行高效的交通管理和任务调度,异构移动机器人系统共存于同一应用现场的情况将会越来越多地出现。 一部分新型的移动机器人管理系统将走向分布式和云端部署,并具有可靠冗余能力;可以支持在线的地图和策略更新,以适应变化的运行路线和调度策略;能够对具有SLAM绕行能力的移动机器人进行优化调度,高效、灵活地管理系统中的任务分配和交通管控;通过一定的标准化手段,管控好同一现场异构机器人系统之间的协调运行。   4 同构仿真、数字孪生,为客户提供一站式服务 客户在做智能化、自动化改造的过程中,从方案设想,到方案设计和实际投入,中间会经过漫长的决策链,通常这个决策过程依赖设计人员的经验,这样可能会导致规划结果和实际需求产生较大的偏差,导致浪费或工期延误。 一套功能完备的同构仿真系统可以避免设计过程中的人为偏差,并且能够极大提高评估效率;可以提供规划、仿真、实施、运营等一站式解决方案,实现同构仿真和数字孪生,极大减少机器人项目规划风险,提高运维效率。 5 应用场景将进一步扩大 在技术进一步发展的基础上,未来移动机器人的应用场景将进一步扩大,将逐渐深入到制造业的各个领域及环节。而伴随着终端客户对智能化需求的进一步提高,未来单个以AGV为主的项目将会越来越少,因此,不同类型的移动机器人以及移动机器人与其他自动化设备如何实现协调运作将成为考验企业方案实施能力的关键。此外,从室内走向室外,园区物流等半封闭场景的户外应用也将是移动机器人发展的方向之一。 除以上三个看法外,未来工业应用移动机器人技术还将与人工智能、移动互联网、大数据处理等技术加速融合,从而创造出新的技术、产品和应用模式。   互联网裁人,移动机器人行业“抢人”? 2022年,不少互联网企业纷纷选择以“优化结构”等方式大量裁员,引起大家热烈讨论。 在这波裁员浪潮中,移动机器人行业未受到影响,依旧在大规模地招兵买马。最典型的现象是,有些移动机器人企业在短短时间内,从几百人规模迅速扩招到破千人,如今这个速度还在继续。 这一鲜明的对比背后,移动机器人企业的思考逻辑是什么? 企业抢滩登陆,打响人才“争夺战” 当前,移动机器人迎来商业化落地阶段,市场潜力不断加速释放,高工机器人产业研究所(GGII)数据显示,2020-2025年中国移动机器人市场规模年复合增速超35%,至2025年中国移动机器人市场规模将突破250亿元。 市场放量前夜,移动机器人企业都在大力布局,抢滩登陆。除产品迭代更新、核心技术持续研发、解决方案持续完善外,“人才”的争夺战也成为了企业抢占市场份额的必要手段。 据高工移动机器人了解,在移动机器人企业的招人计划中,企业对于算法工程师、嵌入式工程师等高端人才求贤若渴,开出了极其丰厚的薪资。例如,招聘一个机器人算法工程师,年薪在40万-50万左右。 同时,为了获得人才的“青睐”,各大移动机器人企业也在招聘上各显神通,凸显自身优势吸引人才。

消息队列

What: 消息队列(Message Queue)是一种应用间的通信方式,消息发送后可以立即返回,由消息系统来确保消息的可靠传递。消息发布者只管把消息发布到 MQ 中而不用管谁来取,消息使用者只管从 MQ 中取消息而不管是谁发布的。这样发布者和使用者都不用知道对方的存在,消息队列是一种应用间的异步协作机制。 https://www.jianshu.com/p/79ca08116d57   Why: 异步处理,应用解耦,流量削峰,日志,最终一致性 https://blog.csdn.net/weixin_52622200/article/details/119765008   How: Rabbitmq

LeetCode 0085 Maximal Rectangle

原题传送门 1. 题目描述 2. Solution 1 1、思路分析 以 example 1. 为例 matrix = [ [1,0,1,0,0], [1,0,1,1,1], [1,1,1,1,1], [1,0,0,1,0] ] 分析: 遍历 行(row) row = 1: 可以得到 heights = [1, 0, 1, 0, 0] 套用 Q84 row = 2: -> heights = [2, 0, 2, 1, 1] ...... 2、代码实现 package Q0099.Q0085MaximalRectangle; import java.util.ArrayDeque; import java.util.Deque; /* 以 example 1. 为例 matrix = [ [1,0,1,0,0], [1,0,1,1,1], [1,1,1,1,1], [1,0,0,1,0] ] 分析: 遍历 行(row) row = 1: 可以得到 heights = [1, 0, 1, 0, 0] 套用 Q84 row = 2: -> heights = [2, 0, 2, 1, 1] .

处理机管理——信号量机制

信号量机制 用户进程可以通过使用操作系统提供的一对原语来对信号量进行操作,从而很方便的实现了进程互斥、进程同步。 信号量其实就是一个变量(可以是一个整数,也可以是更复杂的记录型变量),可以用一个信号量来表示系统中某种资源的数量,比如:系统中只有一台打印机,就可以设置一个初值为1的信号量。 原语是一种特殊的程序段,其执行只能一气呵成,不可被中断。原语是由关中断/开中断指令实现的。软件解决方案的主要问题是由“进入区的各种操作无法一气呵成”,因此如果能把进入区、退出区的操作都用“原语”实现,使这些操作能“一气呵成”就能避免问题。 一对原语:wait(S)原语和signal(S)原语,可以把原语理解为我们自己写的函数,函数名分别为wait和signal,括号里的信号量s其实就是函数调用时传入的一个参数。 wait、signal原语常简称为p、v操作 整型信号量 用一个整数型的变量作为信号量,用来表示系统中某种资源的数量。 Eg:某计算机系统中有一台打印机 与普通整数变量的区别:对信号量的操作只有三种,即初始化、p操作、v操作 “检查”和“上锁”一气呵成,避免了并发、异步导致的问题 存在的问题:不满足“让权等待”原则,会发生“忙等” 记录型信号量 用记录型数据结构表示的信号量。 如果剩余资源数不够,使用block原语使进程从运行态进入阻塞态,并挂到信号量s的等待队列(即阻塞队列)中 释放资源后,若还有别的进程在等待这种资源,则使用wakeup原语唤醒等待队列中的一个进程,该进程从阻塞态变为就绪态 wait(S)、signal(S)也可以记为P(S)、V(S),这对原语可用于实现系统资源的“申请”和“释放” S.value的初值表示系统中某种资源的数目。 对信号量S的一次p操作意味着进程请求一个单位的该类资源,因此需要执行S.value--,表示资源数减1,当s.value<0时表示该类资源己分配完毕,因此进程应调用block原语进行自我阻塞(当前运行的进程从运行态→阻塞态),主动放弃处理机,并插入该类资源的等待队列s.L中。可见,该机制遵循了“让权等待”原则, 不会出现“忙等”现象。 对信号量S的一次v操作意味着进程释放一个单位的该类资源,因此需要执行S.value++,表示资源数加1,若加1后仍是S.value<=0,表示依然有进程在等待该类资源,因此应调用wakeup原语唤醒等待队列中的第一个进程(被唤醒进程从阻塞态→就绪态)。