操作系统与Linux操作命令


大部分摘自网络。

操作系统

【操作系统】常用总结

1.进程与线程的区别

操作系统管理的计算机系统资源包括:中央处理器(CPU)、主存储器(内存/外存)、外部设备(I/O)、数据、程序。
操作系统的主要功能有:1、进程管理;2、存储管理;3、设备管理;4、文件管理;5、作业管理。

进程可以认为是程序执行时的一个实例。进程是系统进行资源分配的独立实体,且每个进程拥有独立的地址空间。(即资源的分配和调度的一个独立单元)
进程控制块(Process Control Block, PCB):保存运行期间进程的数据,PCB 是进程存在的唯一标志。
对线程最基本的理解就是“轻量级进程”,它是一个基本的 CPU 执行单元,也是程序执行流的最小单元,由线程 ID、程序计数器、寄存器集合和堆栈组成。(即 CPU 调度的基本单元)
线程控制块(Thread Control Block, TCB):保存运行期间线程的数据,TCB 是线程存在的唯一标志。
 - 线程属于进程,是进程的一个实体,是被系统独立和分配的基本单位。
 - 线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可以与同属一个进程的其他线程共享进程所拥有的全部资源。
 - 一个进程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行。

进程与线程的区别?
(1)进程有自己的独立地址空间,线程没有
(2)进程是资源分配的最小单位,线程是CPU调度的最小单位
(3)进程和线程通信方式不同(线程之间的通信比较方便。同一进程下的线程共享数据(比如全局变量,静态变量),通过这些数据来通信不仅快捷而且方便,当然如何处理好这些访问的同步与互斥正是编写多线程程序的难点。而进程之间的通信只能通过进程通信的方式进行。)
(4)进程上下文切换开销大,线程开销小
(5)一个进程挂掉了不会影响其他进程,而线程挂掉了会影响其他线程
(6)对进程操作一般开销都比较大,对线程开销就小了
(比如当我们打开一个word程序,就是打开了一个进程,其实已经同时开启了多个线程,这些线程一个负责显示,一个接受输入,一个定时进行存盘,这些线程一起运转让我们感到我们的输入和屏幕显示同时发生,而不用键入一些字符等好长时间才能显示到屏幕上。)

为什么进程上下文切换比线程上下文切换代价高?
进程切换分两步:

1.切换页目录以使用新的地址空间

2.切换内核栈和硬件上下文

对于linux来说,线程和进程的最大区别就在于地址空间,对于线程切换,第1步是不需要做的,第2是进程和线程切换都要做的。

切换的性能消耗:

1、线程上下文切换和进程上下问切换一个最主要的区别是线程的切换虚拟内存空间依然是相同的,但是进程切换是不同的。这两种上下文切换的处理都是通过操作系统内核来完成的。内核的这种切换过程伴随的最显著的性能损耗是将寄存器中的内容切换出。

2、另外一个隐藏的损耗是上下文的切换会扰乱处理器的缓存机制。简单的说,一旦去切换上下文,处理器中所有已经缓存的内存地址一瞬间都作废了。还有一个显著的区别是当你改变虚拟内存空间的时候,处理的页表缓冲(processor’s Translation Lookaside Buffer (TLB))被全部刷新,这将导致内存的访问在一段时间内相当的低效。但是在线程的切换中,不会出现这个问题。

切换开销
最显著的性能损耗是将保存寄存器中的内容

CPU高速缓存失效

页表查找是一个很慢的过程,因此通常使用Cache来缓存常用的地址映射,这样可以加速页表查找,这个cache就是TLB.当进程切换后页表也要进行切换,页表切换后TLB就失效了,cache失效导致命中率降低,那么虚拟地址转换为物理地址就会变慢,表现出来的就是程序运行会变慢
在这里插入图片描述

区别:
1.引入线程的系统当中,进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位。
2.并发性:进程间可以并发,同一进程的多个线程间可以并发。
3.拥有资源:线程不拥有自己的资源,同一个进程中可以包括多个线程,这些线程共享整个进程的资源(寄存器、堆、上下文)。
4.系统开销:线程切换仅需保存少量寄存器内容,不涉及存储器管理方面的操作,因此代价小于进程切换代价
6.进程的创建调用 fork 或者 vfork,而线程的创建调用 pthread_create;
7.进程结束后它拥有的所有线程都将销毁,而线程的结束不会影响同个进程中的其他线程的结束。
8.线程是轻量级的进程,它的创建和销毁所需要的时间比进程小很多,所有操作系统中的执行功能都是创建线程去完成的。
9.线程有自己的私有属性 TCB、线程 id、寄存器、硬件上下文;而进程也有自己的私有属性进程控制块 PCB,这些私有属性是不被共享的,用来表示一个进程或一个线程的标志。
在这里插入图片描述

  • 进程间的通信方式:管道、消息队列、信号、共享内存
  • 线程间的通信方式:全局变量、消息队列(针对于python中的threading模块来说)

2.常见锁

4.1 互斥锁
4.2 多重入锁(允许一个进程/线程多次拿到锁)
4.3 自旋锁 (CPU不断检查锁是否可用)
4.***
4.5 条件
4.6 信号量 (一次允许多个线程操作锁对象)
4.7 读写锁 (一次只有一个写者,多个读者)

3.死锁的概念、原因、解决方法

(1)概念:死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所占用不会释放的资源而处于的一种永久等待状态。死锁的四个必要条件:
• 互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用。
• 请求与保持条件(Hold and wait):进程每次申请它所需要的一部分资源。在等待一新资源的同时,进程继续占用已分配到的资源。
• 非剥夺条件(No pre-emption):进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即 只能由获得该资源的进程自己来释放。
• 循环等待条件(Circular wait):系统中若干进程组成环路,该环路中每个进程都在等待相邻进程正占用的资源。
java中产生死锁可能性的最根本原因是:1)是多个线程涉及到多个锁,这些锁存在着交叉,所以可能会导致了一个锁依赖的闭环;2)默认的锁申请操作是阻塞的。如,线程在获得一个锁L1的情况下再去申请另外一个锁L2,也就是锁L1想要包含了锁L2,在获得了锁L1,并且没有释放锁L1的情况下,又去申请获得锁L2,这个是产生死锁的最根本原因。

(2)、避免死锁:。只有当以下四个条件同时发生,才会出现死锁,所以只要打破其中一个条件,就可以避免死锁:

互斥,共享资源 X 和 Y 只能被一个线程占用
占有且等待,线程 A 获取到资源 X,在等待资源 Y 的时候,不释放资源 X
不可抢占,其他线程不能强行抢占线程 A 占有的资源
循环等待,线程 A 等待线程 B 占有的资源,线程 B 等待线程 A 的资源
首先,互斥这个条件是没法破坏的,因为锁存在的目的就是互斥,对于剩下的三个条件都可破坏。

静态避免,从任务代码上避免死锁:
• 方法一:破坏死锁的循环等待条件,资源有序分配
• 方法二:破坏死锁的请求与保持条件,使用lock的特性,为获取锁操作设置超时时间。这样不会死锁(至少不会无尽的死锁),资源一次性分配
• 方法三:设置一个条件遍历与一个锁关联。该方法只用一把锁,没有chopstick类,将竞争从对筷子的争夺转换成了对状态的判断。仅当左右邻座都没有进餐时才可以进餐。提升了并发度。
动态避免,从资源分配入手:
算法一:银行家算法:Dijkstra E W 于 1968 年提出银行家算法。之所以称为银行家算法,是因为该算法可用于银行系统。

新进程进入系统时,它必须说明各类资源类型的实例的最大需求量,这一数量不能超过系统各类资源的总数。 当进程申请一组资源时,该算法需要检查申请者对各类资源的最大需求量:

  • 如果系统现存的各类资源的数量可以满足当前它对各类资源的最大需求量时,就满足当前的申请;
  • 否则,进程必须等待,直到其他进程释放足够的资源为止。

换言之,仅当申请者可以在一定时间内无条件地归还它所申请的全部资源时,才能把资源分配给它。

算法二:哲学家算法:
问题描述
有五个哲学家,他们的生活方式是交替地进行思考和进餐。他们共用一张圆桌,分别坐在五张椅子上。在圆桌上有五个碗和五支筷子,平时一个哲学家进行思考,饥饿时便试图取用其左、右最靠近他的筷子,只有在他拿到两支筷子时才能进餐。进餐完毕,放下筷子又继续思考。

解决方案
方法一:至多只允许四位哲学家同时去拿左筷子,最终能保证至少有一位哲学家能进餐,并在用完后释放两只筷子供他人使用。(原理:至多只允许四个哲学家同时进餐,以保证至少有一个哲学家能够进餐,最终总会释放出他所使用过的两支筷子,从而可使更多的哲学家进餐。)
方法二:仅当哲学家的左右手筷子都拿起时才允许进餐。(原理:多个临界资源,要么全部分配,要么一个都不分配,因此不会出现死锁的情形。)
方法三:规定奇数号哲学家先拿左筷子再拿右筷子,而偶数号哲学家相反。(最后总会有一个哲学家能获得两支筷子而进餐。)

(3)、死锁解除
①资源剥夺法
挂起某些死锁资源,抢占其资源分配给其他的死锁进程
缺点:被挂起的进程可能会导致饥饿

②终止进程法
强制终止部分、甚至全部死锁进程,并剥夺其所占有的资源
缺点:付出代价较大,有些进程已近结束,终止就会功亏一篑

③进程回退法
让一个或多个进程回退到不会发生死锁的地步
缺点:要求系统记录进程的历史信息,设置还原点,浪费系统资源

4.内存换出算法

1.FIFO先进先出
思想:淘汰最先进入的页面,采用队列实现,先进先出
缺点:可能会频繁地换入换出,影响效率

2.OPT最佳算法
思想:淘汰以后不需要使用或者最远才会用到的页
缺点:实际操作中无法预测未来页的使用情况

3.LRU最久未使用淘汰算法
思想:淘汰最长时间没有被使用的页。软件可以用双向链表实现,访问的时候就把该页移到头部,淘汰时淘汰尾部。

4.LFU最不经常使用淘汰算法
思想:淘汰访问频率最小的页,以次数为参考。新加入的页放在末尾,计数器置为1,每次访问计数器+1,并重新按照计数器大小排序,淘汰计数器最小的页

5.进程调度算法

写得比较详细的博客:操作系统的常见进程调度算法
1.先来先服务(FCFS,first come first served)
算法原理:进程按照它们请求CPU的顺序使用CPU.
算法优点:易于理解且实现简单,只需要一个队列(FIFO),且相当公平
算法缺点:比较有利于长进程,而不利于短进程,有利于CPU 繁忙的进程,而不利于I/O 繁忙的进程
2.短作业优先(SJF, Shortest Job First)
“短进程优先”SPN(Shortest Process Next);这是对FCFS算法的改进,其目标是减少平均周转时间。
算法原理:对预计执行时间短的进程优先分派处理机。通常后来的短进程不抢先正在执行的进程。
算法优点:相比FCFS 算法,该算法可改善平均周转时间和平均带权周转时间,缩短进程的等待时间,提高系统的吞吐量。
算法缺点:对长进程非常不利,可能长时间得不到执行,且未能依据进程的紧迫程度来划分执行的优先级,以及难以准确估计进程的执行时间,从而影响调度性能。
3.高响应比优先(HRRN,Highest Response Ratio Next)
HRN调度策略同时考虑每个作业的等待时间长短和估计需要的执行时间长短,从中选出响应比最高的作业投入执行。
算法原理:响应比R定义如下: R =(W+T)/T = 1+W/T
其中T为该作业估计需要的执行时间,W为作业在后备状态队列中的等待时间。每当要进行作业调度时,系统计算每个作业的响应比,选择其中R最大者投入执行。
算法优点:由于长作业也有机会投入运行,在同一时间内处理的作业数显然要少于SJF法,从而采用HRRN方式时其吞吐量将小于采用SJF 法时的吞吐量。
算法缺点:由于每次调度前要计算响应比,系统开销也要相应增加。

4.时间片轮转法(RR,Round-Robin)
算法原理:让就绪进程以FCFS 的方式按时间片轮流使用CPU 的调度方式,即将系统中所有的就绪进程按照FCFS 原则,排成一个队列,每次调度时将CPU 分派给队首进程,让其执行一个时间片,时间片的长度从几个ms 到几百ms。在一个时间片结束时,发生时钟中断,调度程序据此暂停当前进程的执行,将其送到就绪队列的末尾,并通过上下文切换执行当前的队首进程,进程可以未使用完一个时间片,就出让CPU(如阻塞)。
算法优点:时间片轮转调度算法的特点是简单易行、平均响应时间短。
算法缺点:不利于处理紧急作业。在时间片轮转算法中,时间片的大小对系统性能的影响很大,因此时间片的大小应选择恰当
时间片大小的确定
1.系统对响应时间的要求
2.就绪队列中进程的数目
3.系统的处理能力

5.优先级调度算法
6.多级反馈队列(Multilevel Feedback Queue)
多级反馈队列调度算法是一种CPU处理机调度算法,UNIX操作系统采取的便是这种调度算法。
多级反馈队列调度算法描述:
  1、进程在进入待调度的队列等待时,首先进入优先级最高的Q1等待。
  2、首先调度优先级高的队列中的进程。若高优先级中队列中已没有调度的进程,则调度次优先级队列中的进程。例如:Q1,Q2,Q3三个队列,只有在Q1中没有进程等待时才去调度Q2,同理,只有Q1,Q2都为空时才会去调度Q3。
  3、对于同一个队列中的各个进程,按照时间片轮转法调度。比如Q1队列的时间片为N,那么Q1中的作业在经历了N个时间片后若还没有完成,则进入Q2队列等待,若Q2的时间片用完后作业还不能完成,一直进入下一级队列,直至完成。
  4、在低优先级的队列中的进程在运行时,又有新到达的作业,那么在运行完这个时间片后,CPU马上分配给新到达的作业(抢占式)。
  在多级反馈队列调度算法中,如果规定第一个队列的时间片略大于多数人机交互所需之处理时间时,便能够较好的满足各种类型用户的需要

实际情况中如何选择进程调度算法?
根据是否要关注优先权,如果不考虑优先权可以采用高响应比优先算法,如果考虑优先权可以采用多级反馈队列。

6.线程安全

线程安全: 线程安全是多线程领域的问题,线程安全可以简单理解为一个方法或者一个实例可以在多线程环境中使用而不会出现问题。
产生线程不安全的原因: 在同一程序中运行多个线程本身不会导致问题,问题在于多个线程访问了相同的资源。如,同一内存区(变量,数组,或对象)、系统(数据库,web services等)或文件。实际上,这些问题只有在一或多个线程向这些资源做了写操作时才有可能发生,只要资源没有发生变化,多个线程读取相同的资源就是安全的。

竞态条件 & 临界区
当两个线程竞争同一资源时,如果对资源的访问顺序敏感,就称存在竞态条件。导致竞态条件发生的代码区称作临界区。上例中add()方法就是一个临界区,它会产生竞态条件。在临界区中使用适当的同步就可以避免竞态条件。
当多个线程同时访问同一个资源,并且其中的一个或者多个线程对这个资源进行了写操作,才会产生竞态条件。多个线程同时读同一个资源不会产生竞态条件。

共享资源
允许被多个线程同时执行的代码称作线程安全的代码。线程安全的代码不包含竞态条件。当多个线程同时更新共享资源时会引发竞态条件。因此,了解Java线程执行时共享了什么资源很重要。

局部变量
局部变量存储在线程自己的栈中。也就是说,局部变量永远也不会被多个线程共享。所以,基础类型的局部变量是线程安全的。

判断资源对象是否是线程安全
如果一个资源的创建,使用,销毁都在同一个线程内完成,且永远不会脱离该线程的控制,则该资源的使用就是线程安全的。
可以通过创建不可变的共享对象来保证对象在线程间共享时不会被修改,从而实现线程安全。

引用不是线程安全的!
重要的是要记住,即使一个对象是线程安全的不可变对象,指向这个对象的引用也可能不是线程安全的。

7.设计模式

几种常用的设计模式介绍

Linux常用查询命令

这个链接更详细 Linux 常用操作命令大全-非常详细

【Linux】速查手册

1.文件/目录相关

1.ls 列出当前文件夹下的内容
2.pwd 查看当前所在目录
3.cd 切换目录
. 当前目录 … 上级目录 cd ~ 切换到主目录 cd - 在最近两次操作目录间横跳
4.touch 创建文件
5.mkdir 新建目录
6.rm 删除文件
rm -r 目录名 删除目录 rm -f 强制删除,无该文件也无需提醒 rm -r * 删除当前目录下所有文件和目录
7.cp 复制文件
8.mv 移动文件

2.显示文件内容相关

1.grep 搜索文本 文件名 搜索文本内容
-n 显示行号; -v 不包括该内容的 ; ^a查找以a开头的行; a$ 查找以a结尾的行
2.cat 显示文件完整内容
3.more 分屏显示文件内容
4.less 分屏显示文件内容,上下键控制翻页
5.head 打印文件中的前n行
6.tail 打印文件中的末尾几行
显示10~15行内容 tail 文件名 +10| head +5
7.find
find 目录 -name 搜索字符 搜索名字为xxx的文件 可以使用通配符
find 目录 -size 数据块 搜索大小为xxx的文件,1数据块=0.5kB
+n 大于 -n 小于 n等于
组合条件:-o 或者;-a 并且
find \ -size +163840 -a -size -204800 查找根目录下大于80MB小于100MB的文件
find 目录 -group xxx 查询所属组为xxx的文件
find 目录 -user xxx 查询所属者为xxx的文件
8.wc
wc 文件 -l 统计文件的行数
wc 文件 -w 统计文件的单词数
wc 文件 -c 统计文件的字节数
3.进程与内存相关
1.top 动态实时显示cpu、内存、进程使用情况
2.ps 列出进程
ps -ef | grep xxx 查看xx进程,可以获得pid
ps -a 列出所有运行中的进程
pgrep -l xxx 查看xx进程的pid
netstat -atnp| grep xxx 查询pid

3.kill 杀死进程

kill -9 pid 强制杀死某进程
4.netstat
netstat -atnp | grep xxxx 查看端口号/状态的进程pid
查看端口占用情况 lsof -i
查看指定端口占用情况 lsof -i:端口号
5.free 显示当前内存使用情况
6.df 以字节形式显示磁盘使用情况

4. tail结合grep使用

tail -f log | grep "aaadddd"
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值