进程是系统进行资源分配和调度的基本单位,
成都创新互联是一家专注于网站制作、成都网站制作与策划设计,向阳网站建设哪家好?成都创新互联做网站,专注于网站建设10多年,网设计领域的专业建站公司;建站业务涵盖:向阳等地区。向阳做网站价格咨询:18982081108进程本质上是运行中的程序是动态的,需要将进程运行的当前状态,所需资源等信息保存到进程控制块中,操作系统为了管理进程设计的数据结构叫进程控制块,里面存的字段可以分成进程标识符、处理机状态、进程调度信息、进程控制信息。
2.2 进程状态模型 —简述阻塞、非阻塞、同步、异步—简述为什么发送阻塞?五状态模型:创建、就绪、终止、阻塞。运行
就绪状态:其他资源都准备好了,只差CPU资源的状态,只要在获得CPU使用权就可以随时被调度执行。
创建状态:创建进程是拥有PCB(进程控制块)但其他资源没有就绪为创建状态
先分配PCB(进程控制块)然后插入就绪队列。
操作系统提供fork函数接口创建进程
终止状态:进程结束有系统清理或者归还PCB的状态为终止状态。
阻塞状态:进程因为某种原因(其他设备没有就绪包括磁盘、网卡等)无法继续执行而放弃cpu的使用权,把cpu资源让给其他进程。
进程从就绪状态进行进程调度,分配cpu资源,然后到运行状态,当时间片用完之后进入就绪状态,而在运行状态时因为某些资源没有就绪比如IO请求包括网络IO、磁盘IO、都可能从运行状态切换到阻塞状态,当IO请求完成了进程从阻塞状态切换就绪状态。
阻塞、非阻塞、同步、异步。
阻塞状态(同步):阻塞的话典型的就是IO过程,从调用到返回会经历一段时间。因为比如外围设备包括磁盘。网卡等,在读写数据没有CPU快,所以通常读取数据的时候会经历一段时间,这段时间就是属于阻塞状态。在调用结果返回之前,当前进程会被挂起,只有得到结果才会返回。
同步:进程因为在这段时间并没有干其他事情,而是同步的等待数据返回
非阻塞状态(异步):并没有一直等待数据的返回,而是其他的工作,等到比如IO完成了会通知已经完成,进程再去返回IO任务去读取数据。
异步:进程在IO之后没有进行同步等待,去干其他事情,并且等待IO这个过程准备好之后进行通知,进程接收到通知ready之后再切换回去读取数据。
当一个异步的调用发出之后,调用并不会得到结果而是,被调用者通过状态或者通知,来通知进程获取结果。
总结:同步异步抢到消息通讯机制,阻塞非阻塞抢到进程在等待调用结果的状态。
2.3 PBC是什么?(进程控制块)PCB是进程控制块。
PCB是进程的唯一标识,操作系统调度进程时就是根据每个进程PCB中的信息进行调度的,当决定执行 某个进程后,会根据该进程PCB中保存的信息去恢复上次执行的现场,当分配到的CPU时间片用完 后,需要将当前状态保存到PCB中,以便下次恢复。
PCB组织方式: 通过链表的方式组织成一个个队列,拥有相同状态的进程组成一个队列。 比如就绪进程就会组成就绪队列、因为某些事件而阻塞的进程组成阻塞队列。 也可以将相同状态的PCB按照其他策略排成多个链表
PCB包含进程的属性和状态信息:
线程:
线程是任务调度和执行的基本单位。CPU上真正运行的是线程,但线程本身几乎不拥有资源,线程自己只拥有一点运行时必不可少的资源,如PC、寄存器和栈,但线程可以和同一进程下的其他线程共享进程资源。
进程:
进程是系统进行资源分配和调度的基本单位,
进程本质上是“运行中的程序”,单纯的程序只是保存在磁盘中的一段代码,是静态的,而进程是运行中的代码,是动态的,除了需要保存这段代码外,还需要将进程运行的当前状态,所需资源等信息保存到进程控制块中,操作系统为了管理进程设计的数据结构叫进程控制块,里面存的字段可以分成进程标识符、处理机状态(进程当前运行到什么时候什么状态的一些信息)、进程调度信息、进程控制信息。所以进程由3部分组成:程序段、数据段和进程控制块。
**协程:**比线程更加轻量级,协程不被操作系统内核所管理,完全是用户态的
2.4 进程与线程区别进程切换流程: 进程之间的虚拟地址空间是不同的,所以要先切换页表,清空快表缓存。 切换内核栈和硬件上下文
进程上下文:当一个进程在执行时,CPU的所有寄存器中的值、进程的状态以及堆栈中的内容被称为该进程的上下文
线程切换流程: 线程之间共享进程的虚拟地址空间,所以线程切换不需要切换页表 直接切换内核栈和硬件上下文即可
2.6 并发和并行的区别?并发和并行在一个时间段内的表现都是多个进程得到了运行。
非抢占式:进程获得CPU资源后,一直运行直到进程结束或阻塞才释放CPU使用权。
抢占式:操作系统可以在进程执行时剥夺CPU,分配给其他进程使用。 典型的有:优先级原则、短进程优先原则、时间片原则
进程调度算法:
孤儿进程:子进程的父进程退出,子进程被ID号为1的inti进程收养,作为子进程的父进程.然后init进程会执行wait或waitpid操作,去释放孤儿进程的资源.
危害:孤儿进程没有危害
僵尸进程:子进程先退出,父进程没有通过wait()或者waipid()去回收释放子进程的资源,此时子进程虽然 退出了,但还占有原本的PCB.
危害:当有大量僵尸进程在内存中时,会占据大量PCB,而PCB资源是有限的,所以会导致无法创建新的进程.
处理:父进程退出,让僵尸进程成为孤儿进程,由init进程收养,处理资源回收工作.
守护进程:在后台运行不受终端控制的进程.
进程切换的开销 :1、切换页表 2、切换内核态堆栈 3、将寄存器中的上下文保存到PCB中 4、刷新跳表TLB是为了更快的进行地址翻译而将部分的页表内容缓存
线程切换的开销 :1、切换内核栈 2、切换硬件上下文
进程切换和线程切换,开销差距大就大在页表切换上,因为这个步骤涉及将寄存器中的内容切换出。 还有,进程切换后,由于跳表刷新,所以一段时间内命中率就很低。
2.10 堆和栈的区别堆:程序员分配和释放的空间,不释放则由操作系统回收,形式是链表。
栈:操作系统自动分配释放的空间,保存函数的参数和局部变量,形式是栈。
2.11 用户态&内核态通过系统调用将操作系统整个体系分为用户态和内核态。
一般的操作系统对执行权限进行分级,分别为用户态和内核态。用户态相较于内核态有较低的执行权限,很多操作是不被操作系统允许的,内核态相当于一个介于硬件与应用之间的层,有最高权限,可以执行任何cpu指令,也可以引用任何内存地址,包括外围设备, 例如硬盘, 网卡,权限等级最高。
为什么要有用户态和内核态:为了限制不同程序对数据的访问能力,防止部分程序获取其他程序的数据,或者获取外围设备的数据,发送到网络上提高安全性.
2.12 系统调用:从应用程序访问到系统内核资源,称之为系统调用。
当一个程序从需要操作系统资源的时候,实际上是从【用户态】->【内核态】->【用户态】这样的一个过程。在这个过程中也需要一定的开销,(strace命令监控一次系统调用的开销,可以使用strace -cp 查看一个进程一段时间内的系统调用,我们可以看到每个系统调用的次数以及总时间。)
2.13 如何从用户态进入内核态简单来说有下面几点:
- 保存用户态现场
- 复制用户态参数并且校验
- 执行内核态代码
- 复制执行结果
- 恢复用户态现场
CPU密集型:也叫计算密集型,指的是系统的硬盘、内存性能相对CPU要高,此时读写IO(硬盘/内存)时可以在很短的时间内完成,而CPU还有许多运算要处理,因此CPU负载很高。
通过多线程提高CPU利用率,通常线程数只需要设置为CPU核心数的线程个数。
因为**频繁的切换线程或进程**也是要消耗时间的。因此对于 CPU 密集型的任务来说,线程数/进程数等于 CPU 数是最好的了。
IO密集型:指的是系统的CPU性能相对硬盘、内存要好很多,此时,系统运作,大部分的状况是CPU在等IO (硬盘/内存) 的读写操作,因此,CPU负载并不高。
当线程进行 I/O 操作 CPU 空闲时,启用其他线程继续使用 CPU,以提高 CPU 的使用率。
2.15 系统设计中缓存的作用——存储器的层次结构存储器层次结构分为寄存器、主存、辅存。
局部性原理:CPU访问存储器时。无论是存取指令还是数据,访问的存储单元都趋向于聚集在一个较小的连续区域中。
缓存-主存层次:根据局部性原理通过在CPU与主存之间增加Cache以解决主存速度不足的问题。
主存-辅存层次:根据局部性原理通过增加辅助存储器包括磁盘啥的以解决主存容量不足的问题。
缓存(如redis)的设计:原理也是局部性原理,借鉴操作系统的原理,分离冷热数据,降低热点数据负载,提升吞吐量、并发量、提升服务质量。
2.16 什么是缓冲区溢出?有什么危害?原因是什么?缓冲区溢出是指向计算机缓冲区填充数据时超过了缓冲区大容量,导致数据被写到缓冲区以外。
危害: 程序崩溃 跳转到恶意代码
原因:程序中没有仔细检查用户输入
2.17 操作系统内存管理——缺页中断、内存页 什么是分页?分页是将内存从物理上划分成大小相同的页(linux一般4K),进程所需的数据分别存放在多个页中, 这些页离散地分布在内存中,因此需要一张记录内存逻辑地址到物理地址映射关系的表,也就是页表,具体记录了页号到物理块号的映射。 分页系统中,访问数据需要两次访问内存,第一次访问的是内存中的页表,根据页号和页内偏移量查找并计算出实际物理地址,第二次根据物理地址访问内存取数据。
什么是分段?分段是将进程的逻辑空间划分为若干不同大小的段(长度由连续逻辑的长度决定),段地址是二维的,一维是段号、二维是段内偏移。因为多个段之间也是离散分布在内存中的,所以需要段表来记录逻辑地址到物理地址的映射关系。
分页和分段的区别?先将逻辑空间按段式管理分成若干段,在将段空间按页式管理分成若干页,段页地址就可以通过段号、段内页号、页内地址找到属于那一段那一页。综合两者优点
2.18 虚拟内存有些进程实际需要很大的内存,超过物理内存容量,再加上多道程序设计使每个进程可用的物理内存更加稀缺,物理内存总有不够的时候。
虚拟内存概述:作为操作系统的内存管理技术,把程序使用的内存划分,(根据局部性原理)将部分暂时不用的内存放置到辅存。替换策略发生在缓存-主存层次/主存-辅存层次。解决速度/容量问题。如果访问页不在内存,则发出缺页中断,发起页面置换。
逻辑地址空间:指进程可以使用的内存空间,大小仅受CPU地址长度限制(比如32位的大逻辑空间为4G-- 2^32字节, 2^32字节)进程运行时可以使用的相对地址空间。
物理地址空间:物理内存的存储空间,进程运行时在物理内存分配和使用的地址空间。
逻辑地址空间需要转换到物理地址空间,是映射关系。
缺页中断:当进程读取的页号在页表中不存在时,会触发缺页中断,处理缺页中断的方法是从外存中找出目标页,然后装入内存中.
具体做法:
从外存中找到目标页
检查当前内存中的空闲是否足够目标页装入
若空间足够,则直接装入目标页,更新页表,中断处理结束
若空间不够,则执行页面置换算法,淘汰页面直到空间足够为止,然后装入目标页,中断处理结束
注意如果淘汰页被修改过,则要执行淘汰页的备份
页面置换时机:高速缓存(需要从主存载入数据)以及主存页面(需要从辅存载入数据)的替换。
先进先出算法(FIFO):队列式算法,页面以链表形式组织,新页装入时,淘汰链表头的最旧页(双向链表实现)
优点:简单、易于实现
缺点:效率不高,驻留最久的页不一定就是最长时间不使用的页
最不经常使用算法(LFU):优先淘汰最不经常使用的字块,需要额外的空间记录字块的使用频率。加入新页时增加频率,淘汰最低的
最近最少使用算法(LRU):
1)链表:
优先淘汰一段时间没有使用的页面,表头存最近访问的页,表尾存最久未用的页。如果访问目标页,则将该页移向表头,其他页相应地也移动,挤掉表尾的页。
优点:效果好
缺点:维护链表的开销太大
2)链表+哈希表=哈希链表:
查找快, 可以想到哈希表, 但是哈希表是乱序的;有序, 可以想到链表, 链表插入、和删除都很快, 但是查询是O(n);集合一下就是哈希链表: , 结构如下:
借助上图结构, 分析上面的三个条件:
涉及到链表的删除操作, 因为通过哈希表定位到某一个链表中的节点, 想要删除时, 需要知道前驱节点的指针。
哈希表里面已经保存了 key ,那么链表中为什么还要存储 key 和 value 呢,只存入 value 不就行了如果链表中的结点,只有 value 没有 key,那么我们就无法删除哈希表的 key。
时钟算法:类似LRU,首先需要给每个页设置访问位,当某页被访问时,访问位为1,该算法按照先进先出算法的顺序依次遍历内存中所有页,若该页的访问位为0,则将该页换出,若为1,则将该页访问位置为0,暂时不换出给他第二次驻留内存的机会,若遍历到最后一个页,访问位仍然是1,则再从第一个页开始遍历。该算法也叫做最近未使用算法。
优点:性能和开销较均衡
缺点:没有考虑到换出被修改过的页所造成的置换代价
改进时钟算法:淘汰的既要是未被访问过的页面,也要是未被修改过的页面。给页面设置访问位A和修改位M。
A = 0, M = 0 该页最近未被访问,也未被修改过,是最佳淘汰页
A = 0, M = 1 该页最近未被访问,但被修改过,不是最佳的淘汰页
A = 1, M = 0 该页最近被访问过,但未被修改,很可能会再次被访问
A= 1, M = 1 该页最近被访问过,也被修改过,很可能会再次被访问
算法执行流程和简单Clock算法类似:
1、第一轮扫描,目标是 A = 0, M = 0 的页,找到的第一个就作为淘汰页
2、若第一轮失败,则进行第二轮扫描,目标是 A = 0, M = 1 的页,找到的第一个作为淘汰页,且在第二轮扫描期间,将经过的页面 A置为0
3、若第二轮失败,则进行第三轮扫描,目标是第一类页
4、若第三轮失败,则进行第四轮扫描,目标是第二类页,此轮一定能找到淘汰页。
优点:由于换出的是最近未被修改过的页,所以可以减少磁盘IO次数
缺点:该算法执行时扫描轮次变多,开销大
2.20 什么是交换、交换区?操作系统将内存中阻塞的进程暂时移出内存,并将已经就绪的进程移入内存的操作叫做交换。
从操作系统中暂时移出的进程,放在外存的交换区中。
2.21 为什么虚拟地址切换会比较耗时?进行虚拟地址到物理地址的转换就需要去查页表,而查找页表是一个很慢的操作,所以为了加快该过程就会用快表去缓存最近查找过的虚拟地址,但每个进程都有自己的页表,一旦发生进程切换,页表就需要切换,那么快表就会被清空,所以导致进程切换后查快表的命中率非常低,此时大量时间花在查页表上,表现出来的就是程序运行的速度变慢了。
线程切换就不会导致快表失效,因为线程切换无需切换地址空间,所以线程切换比进程切换快。
2.22 什么是内存碎片?如何解决?内存碎片分为内部碎片和外部碎片.
内部碎片分配出去但无法被利用的内存空间,分页系统是以页为单位分配内存空间的,而且页的大小是固定的,这就使得分配给一个进程的多个页中,最后一页往往无法全部利用,由空闲空间,这部分就是内部碎片,直到进程执行结束,其他进程都无法使用这部分空间.
解决方法:采用分段存储,每个段的长度可以不一样.
外部碎片是指那些还没有被分配出去,但是因为空间太小而无法分配给进程的空闲空间,外部碎片因为彼此之间不连续,本身又太小,所以无法被利用,只有通过将外部碎片地址整合在一起,才可以利用起来,但整合外部碎片的开销又比较大.
解决方法:采用分页存储,页与页之间连续,不会产生外部碎片
综合解决方法:采用段页式存储,先对内存分段,然后再将每一段分成大小相同的页
2.23 虚拟地址和物理地址之间是如何进行映射的?通过MMU(内存管理单元)
2.24 LInux软连接与硬链接区别EXT文件系统:
Inode Table :每一个文件(目录)的索引节点,存放Inode的地方,每一个文件(目录)都有一个Inode
Inode:保存文件相关的原信息,包括文件类型、状态、长度、等等。(文件名存放在目录的Inode节点上,而不是文件的Inode)
linux文件=Inode(文件源信息)+block(文件数据)
硬链接直接指向源文件的Inode。
软连接有一个完整的文件包括Inode以及block,block存放的是源文件路径。(快捷方式)
2.25 磁盘冗余阵列——服务器部署的RAID存储RAID(磁盘冗余阵列):利用虚拟化存储技术把多个硬盘组合起来,成为一个或多个磁盘阵列,提示性能减少冗余。
RAID 0:性能是单块性能的N倍,不提供数据校验和冗余,若是某一个磁盘损坏,数据直接丢失,可靠性低
RAID 1:相对RAID0做了冗余,增加镜像磁盘备份,可以做数据恢复
RAID 5:(最常用)增加校验码、海明码,
RAID 1 0:结合RAID 0和RAID 1
2.26 常见的磁盘调度算法?先来先服务:根据进程请求访问磁盘的先后顺序进行调度
优点:实现简单 缺点:本质上接近于随机读取
最短寻道时间优先:选择距离当前磁头最近的访问请求进行服务
优点:平均服务时间较短 缺点:容易让部分服务饿死
扫描算法(电梯算法):选择当前磁头移动方向上与当前磁道距离最近的请求进行服务
优点:扫描算法既考虑了距离,又考虑了方向
死锁就是多个进程间彼此持有对方需要的资源,但又在等待对方释放自己需要的资源的状态。
2.28 为什么产生死锁1、预防死锁
(1)破坏互斥条件:进程申请资源时,为资源进行一次拷贝,进程可以获取资源的拷贝
缺点:实用性不强,拷贝资源的成本极高,当线程数较多时,不适用
(2)摒弃请求和保持条件:必须一次性将进程所需的资源全部分配给进程,否则可以分配的资源也不分配给进程
优点:简单、易于实现、安全
缺点:
(3)摒弃不剥夺条件:当进程得不到新申请的资源时,释放自己已经持有的资源,等到需要时再重新申请;或者设置计时机制,当进程持有资源超过一定时间仍不能完成任务时,会释放已经持有的资源(参考CPU无法成为死锁资源,因为CPU的时间片轮转,让每个进程只能)。
缺点:实现复杂、反复申请资源使得进程无限推迟,降低系统吞吐量。
(4)摒弃环路等待条件:对所有资源进行标号,进程对资源的申请顺序必须按照资源标号升序申请。
优点:资源利用率高、系统吞吐量大
缺点:限制了新资源的加入、使用顺序与申请顺序不同,导致资源浪费。
2、避免死锁
(1)安全与不安全状态。进程动态申请资源,每次申请资源时系统都会评估分配该资源的安全性,若 此次分配不会导致系统进入不安全状态,就将资源分配给进程。
(2)银行家算法。可利用资源向量、大需求矩阵、分配矩阵、需求矩阵。 进程P的请求向量
1)若请求向量<= 需求矩阵,转入第二步,否则出错,因为请求资源数大于它宣布的大数
2)若请求向量<= 可利用资源,转入第三步,否则表示资源不够,进程等待
3)系统试探性地将资源分配给进程,修改 可利用资源向量、分配矩阵、需求矩阵
4)系统执行安全性算法,检查资源分配后是否处于处于安全状态,若安全则执行此次分配,若不安全 则撤销此次分配。
3、检测死锁
(1)资源分配图 + 死锁定理
(2)死锁检测算法 = 银行家算法中的安全检测方法
4、解除死锁
(1)剥夺资源。从其他进程中剥夺足够的资源给死锁进程。
(2)撤销进程。简单的是清除全部死锁进程,温和一点的是逐个清除死锁进程,直到死锁状态消除为 止。
2.31 简述各种锁的概念乐观锁/悲观锁:
悲观锁每次操作都会加锁,乐观锁默认不加锁
悲观锁适合写操作多的场景,乐观锁适合读操作多的场景,可以提升并发度
无锁/偏向锁/轻量级锁/重量级锁:
(不放弃CPU)
等待锁释放。公平锁/非公平锁:
公平锁:有一个先进先出的等待队列,不会出现饥饿等待
非公平锁:可以插队,没有插上的话也是插在等待队列尾部。会出现饥饿等待
可重入锁/非可重入锁:
重入:任意线程获得锁之后,这个线程再次获取该锁时不会阻塞
可重入锁:又名递归锁,同一个线程在外层方法获取锁的时候,在进入该线程的内层方法会自动获取锁,不会因为之前已经获取过还没释放而阻塞。
非可重入锁:会出现死锁
共享锁/排它锁:
共享锁:该锁可以被多个线程持有,获得共享锁的线程只能读不能写。
排它锁:又名互斥锁。一次只能被一个线程持有。
2.32 线程间通信——互斥锁和自旋锁的区别——线程间同步?互斥锁:互斥锁就是可以拒绝另一个线程访问临界资源的一种锁。会让出CPU,可以通过互斥锁保证串行访问资源以保护这个临界资源。是最简单的线程间通信方法。
自旋锁(spin_lock):拒绝另一个线程访问临界资源的一种锁,不过与互斥锁的实现原理不同。自旋锁不会让出CPU,是一种忙等待状态。为了避免进程或者线程上下文切片的开销,不适合单核CPU。
读写锁:是一种特殊的自旋锁,准许多个读者同时访问提高读性能,不过写操作则是互斥锁,适合多读少写的情况,因为读取的时候不会改变临界资源。
条件变量:条件变量本质也是一个条件变量,它的功能是阻塞线程,直至接收到“条件成立”的信号后,被阻塞的线程才能继续执行。
相对复杂的线程同步方法。允许线程睡眠,直到满足某种条件,当满足条件,发送信号通知唤醒。wait——》signal
例如:生产消费关系会用到,缓冲区空或者满。当生产者生产一份数据的时候,唤醒可能等待的消费者,
2.33 进程间通信——进程间通信同步方式?信号量:
允许多个进程同时访问统一资源,描述信号量的结构体,保存了两个变量,一个是整型变量 value,另一个是进程链表L,对信号量的操作只有P和V两个原子操作。执行P操作时,会先将value值减一,若此时 value小于零,则说明临界资源暂时不可访问,于是进程会阻塞,否则顺利访问资源;执行V操作时,会先将value值 加一,如果此时有进程正在睡眠等待此信号量,则唤醒此进程。。
- 当信号量初始值为 1 时,信号量等同于互斥锁。
- 当信号量初始值为 0 时,代表是同步信号量,可以用于控制两个进程的前驱关系。
AND信号量机制:
如果进程P和进程Q都需要临界资源A和临界资源B才能工作,那么有可能造成P持有 A、Q持有B的情况,此时两个进程都在等待对方释放资源,互相持有对方需要的临界资源,形成死锁。为了解决死锁,进程引入了AND信号量机制,就是指进程需要的全部资源,要么全部分配给进程,如果有任意一个资源无法分配,就将可以分配的那些资源也放弃,等价于将分配进程所需资源这个操作原子化。
缺点:用信号量实现进程同步会造成系统大量P操作和V操作,效率较低。
管道:例如:匿名管道 :cat 文件 | grep ERROR,命名管道 mkfifo 命名
优点:实现简单
缺点: 1、通信效率低,不适合进程间频繁通信,先入先出
2、通信格式只支持字节流数据。
消息队列:
优点:
缺点:
共享内存:
优点:避免了用户态到内核态的数据拷贝,直接对内存进行读写,是最快的进程间通信。
缺点:缺少进程同步机制,多个进程可能同时对共享内存进行写入,造成数据不一致,需要用到互斥锁或信号量。
信号(事件):
事件机制就是一个进程完成任务后,发送信号主动唤醒另一个sleep的线程执行任务,没有收到唤醒信号的线程就会处于sleep状态,也可以实现不同进程中的线程间的同步。
仅起到通知作用没有数据交流,不同信号使用不同的值,Linux通过kill -l 查看信号列表:比如Ctrl c 用的信号值是2.
套接字:
跨网络跨主机进程间通信。TCP连接本质上就是由两个套接字组成的跨网络进程间通信。 传输层提供主机不同进程之间通信。
套接字=IP(标识主机)+端口(标识进程)
套接字类型有3种:TCP字节流通信、UDP数据报通信、本地进程间通信。
UnIx域套接字:可以用于单机进程间通信,提供网络套接字类似的功能,因为无需经过完整的网络协议栈所以在单机上从性能方面考虑的话优先使用域套接字。
2.34 简述无所数据结构原理——CAS原理与无锁技术?大量使用锁的弊端:
原子性:指一系列操作不能被中断的特性,这一些列操作要么全部执行,要不都不执行,不存在部分执行。
无锁是一种乐观的策略,它假设所有对资源的访问都是没有冲突的,因此所有线程都可以不用阻塞的持续执行,一旦遇到冲突,无锁采用CAS(Compare And Swap)来鉴别冲突,一旦检测到冲突,则重试当前操作直到没有冲突为止。
CAS实际上是一个原子性的CPU指令。
具体思想:
CAS包含三个参数(内存地址,旧值,新值)只有当内存地址取的值与旧值一致时,才会把内存中的值更新为最新的值;若不等,则说明该值被其他线程修改了。每次CAS操作时,一定有一个线程会成功更新变量,而其他失败的线程不会挂起,而是允许继续重试,直到成功为止。
优点:
缺点:
1 ABA问题
ABA问题是指在CAS操作时,其他线程将变量值A改为了B,但是又被改回了A,等到本线程使用期望值A与当前变量进行比较时,发现变量A没有变,于是CAS就将A值进行了交换操作,但是实际上该值已经被其他线程改变过。
解决办法: 在变量前面加上版本号,每次变量更新的时候变量的版本号都+1,即A->B->A就变成了1A->2B->3A。只要变量被某一线程修改过,变量对应的版本号就会发生递增变化,从而解决了ABA问题。
2 循环时间长开销大
分布式部署的比如集群、微服务。服务节点之间需要通信的并且数据有强一致性要求和并发量要求。
方案:
1 redis 2 Zookeeoer 3 ETCD(自己查一下)
4 MySQL:用UNIQUE KEY 表级唯一,不能重复插入,通过MySQL保证同一个Key只有一个节点能插入成功,通过删除记录释放锁,存在单点问题。
Linux五种IO模型阻塞式I/O
非阻塞式I/O
I/O复用(select,poll,epoll等)
信号驱动式I/O(SIGIO)
异步I/O(POSIX的aio_系列函数)
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧