豫ICP备17040950号-2

聊聊CPU的LOCK指令

在多线程操作中,可能最经常被提起的就是数据的可见性、原子性、有序性。不管是硬件方面、软件方面都在这三方面做了很足的工作,才能保证程序的正常运行。

之前发表过一篇文章聊聊缓存一致性协议 如果感兴趣的话可以去阅读一下,里面谈到了缓存一致性的实现和处理过程,读完之后可以仔细去细想一下缓存一致性协议到底解决了什么问题。个人理解缓存一致性协议解决了CPU层面的可见性和一致性问题,阅读到这里可以在这里停下来,仔细回想一下缓存一致性的原理,它通过监听共享总线上消息,对自己缓存中的数据修改不同的状态,来保证数据的一致性,对自己缓存中的数据失效后,下次读取会从主存中直接读取最新的数据 ,可以保证可见性,同时保证各缓存中的数据是一致的。

聊聊缓存一致性协议

什么缓存一致问题

在谈缓存一致性协议之前我们先了解一下缓存一致性问题是什么,它是怎么出现的。

现在处理器的处理能力要远胜于主内存(DRAM),主内存执行一次内存读写操作,所需的时间可能足够处理器执行上百条的指令,为了弥补处理器与主内存处理能力之间的鸿沟,引入了高速缓(Cache),来保存一些CPU从内存读取的数据,下次用到该数据直接从缓存中获取即可,以加快读取速度,随着多核时代的到来,每块CPU都有多个内核,每个内核都有自己的缓存,这样就会出现同一个数据的副本就会存在于多个缓存中,在读写的时候就会出现数据 不一致的情况。

操作系统中锁的原理

  • 概述

    为了保证数据的一致性,在多线程编程中我们会用到锁,使得在某一时间点,只有一个线程进入临界区代码。虽然不同的语言可能会提供不同的锁接口,但是底层调用的都是操作系统的提供的锁,不同的高级语言只是在操作系统的锁机制基础上进行了些封装而已,要真正理解锁,还是得看操作系统是怎么实现锁的。

  • 锁的本质

    所谓的锁,本质上只是内存中的一个整形数,不同的数值表示不同的状态,比如1表示空闲状态和加锁状态。加锁时,判断锁是否空闲,如果空闲,修改为加锁状态,返回成功,如果已经上锁,返回失败,解锁时,就把锁状态修改为空闲状态。        加锁和解锁看起来都很简单,但是os是怎么保证锁操作本身的原子性呢? 在多核环境中,两个核上的代码同时申请一个锁,两个核同时读取锁变量,同时判断锁是空闲的,再各自修改锁变量为上锁状态,都返回成功,这样两个核同时获取到了锁, 这种情况可能吗? 当然是不可能的,那么os是通过什么手段来保证锁操作本身的原子性的呢?我们可以把上锁的过程具体表示为:

程序员的浪漫-浏览器控制台输出炫丽色彩

大家有没有注意到在有些网站中,当我们打开F12的时候,里边会有console内容,这些内容还是有样式的,如果之前没有见到过,你可以打开百度首页,按下F12,里边会有百度的招聘信息,或者打开京东首页、知乎首页,都会看到一些个性的招聘信息,我们自己写的console.log(),在浏览器中是没有样式的,这是怎么做到的呢?

其实浏览器js中的console是可以自定义样式的,可以显示缤纷的颜色,甚至图片。你想到的差不多都可以实现!

用法示例:

%c 代表之后的文本会使用第二个参数给定的css样式来格式化

1
console.log("%c一些文本 ", "css 代码");

展示效果:

jsbasicconsoleskill0101.png