操作系统总结

操作系统

内核态和用户态

  • 内核态是操作系统管理程序执行时所处的状态,能够执行包含特权指令在内的一切指令,能够访问系统内所有的存储空间。

  • 用户态是用户程序执行时处理器所处的状态,不能执行特权指令,只能访问用户地址空间。

  • 处理器从用户态切换到内核态的方法有三种:

    1. 系统调用是操作系统的最小功能单位,是操作系统提供的用户接口,系统调用本身是一种软中断。
    2. 异常,也叫做内中断,是由错误引起的,如文件损坏、缺页故障等。
    3. 外部中断,是通过两根信号线来通知处理器外设的状态变化,是硬中断。

进程 vs 线程

  1. 一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。线程依赖于进程而存在。
  2. 进程在执行过程中拥有独立的地址空间,而多个线程共享进程的地址空间。(资源分配给进程,同一进程的所有线程共享该进程的所有资源。同一进程中的多个线程共享代码段(代码和常量),数据段(全局变量和静态变量),扩展段(堆存储)。但是每个线程拥有自己的栈段,栈段又叫运行时段,用来存放所有局部变量和临时变量。)
  3. 进程是资源分配的最小单位,线程是CPU调度的最小单位。
  4. 通信:由于同一进程中的多个线程具有相同的地址空间,使它们之间的同步和通信的实现,也变得比较容易。进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信(需要一些同步方法,以保证数据的一致性)。
  5. 进程编程调试简单可靠性高,但是创建销毁开销大;线程正相反,开销小,切换速度快,但是编程调试相对复杂。
  6. 进程间不会相互影响;一个进程内某个线程挂掉将导致整个进程挂掉。
  7. 进程适应于多核、多机分布;线程适用于多核。

进程通信方式

1)首先,最简单的方式就是管道,管道的本质是存放在内存中的特殊的文件。也就是说,内核在内存中开辟了一个缓冲区,这个缓冲区与管道文件相关联,对管道文件的操作,被内核转换成对这块缓冲区的操作。管道分为匿名管道和有名管道,匿名管道只能在父子进程之间进行通信,而有名管道没有限制。

2)虽然管道使用简单,但是效率比较低,不适合进程间频繁地交换数据,并且管道只能传输无格式的字节流。为此消息队列应用而生。消息队列的本质就是存放在内存中的消息的链表,而消息本质上是用户自定义的数据结构。如果进程从消息队列中读取了某个消息,这个消息就会被从消息队列中删除。

3)消息队列的速度比较慢,因为每次数据的写入和读取都需要经过用户态与内核态之间数据的拷贝过程,共享内存可以解决这个问题。所谓共享内存就是:两个不同进程的逻辑地址通过页表映射到物理空间的同一区域,它们所共同指向的这块区域就是共享内存。如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程。

对于共享内存机制来说,仅在建立共享内存区域时需要系统调用,一旦建立共享内存,所有的访问都可作为常规内存访问,无需借助内核。这样,数据就不需要在进程之间来回拷贝,所以这是最快的一种进程通信方式。

4)共享内存速度虽然非常快,但是存在冲突问题,为此,我们可以使用信号量和 PV 操作来实现对共享内存的互斥访问,并且还可以实现进程同步。

5)信号是进程通信机制中唯一的异步通信机制,它可以在任何时候发送信号给某个进程。通过发送指定信号来通知进程某个异步事件的发送,以迫使进程执行信号处理程序。信号处理完毕后,被中断进程将恢复执行。用户、内核和进程都能生成和发送信号。

6)上面介绍的 5 种方法都是用于同一台主机上的进程之间进行通信的,如果想要跨网络与不同主机上的进程进行通信,就需要使用 Socket 通信。另外,Socket 也能完成同主机上的进程通信。

线程通信方式

1)共享内存:多个线程共享同一块内存空间,通过对内存的读写操作实现线程间的信息交换。可以使用 synchronized 关键字或 Lock 接口等机制来确保线程安全。

2)消息传递:多个线程之间通过消息传递实现信息交换。在Java中,可以使用wait()、notify()和notifyAll()等方法来实现线程间消息传递。wait()方法会使当前线程等待,直到其他线程调用notify()或notifyAll()方法唤醒它;notify()方法会随机唤醒等待队列中的一个线程;notifyAll()方法会唤醒等待队列中的所有线程。

3)信号量:通过信号量机制实现线程间的信息交换。Java中的 Semaphore 类就是一个信号量实现。

4)管道:管道是一种特殊的流,用于在线程之间传递数据。Java 中的 PipedInputStream 和 PipedOutputStream 类就是管道的实现。

5)RPC调用:远程过程调用(RPC)是一种跨网络进行的远程调用,可以实现在不同的线程或机器之间进行信息交换。

6)互斥锁(Mutex):用于同步访问共享资源,防止多个线程同时访问共享资源,产生冲突。
7)条件变量(Condition Variable):用于线程之间的协调和通信,一个线程可以通过条件变量等待某个条件的出现,另一个线程可以通过条件变量通知正在等待的线程。

进程状态转换

  • 就绪状态:进程具备运行条件,等待系统分配处理器以便运行的状态。当进程已分配到除CPU以外的所有必要资源后,只要再获得CPU,便可立即执行,进程这时的状态称为就绪状态。在一个系统中处于就绪状态的进程可能有多个,通常将它们排成一个队列,称为就绪队列。
  • 运⾏状态:进程占有处理器正在运行的状态。进程已获得CPU,其程序正在执行。在单处理机系统中,只有一个进程处于执行状态;在多处理机系统中,则有多个进程处于执行状态。
  • 阻塞状态:又称等待态,指进程不具备运行条件,正在等待某个时间完成的状态。一个进程正在等待某一事件发生(例如请求I/O而等待I/O完成等)而暂时停止运行,这时即使把处理机分配给进程也无法运行,故称该进程处于阻塞状态。
  • 创建状态:对应于进程被创建时的状态,尚未进入就绪队列。创建一个进程需要通过两个步骤:1.为新进程分配所需要的资源和建立必要的管理信息。2.设置该进程为就绪态,并等待被调度执行。
  • 结束状态:指进程完成任务到达正常结束点,或出现无法克服的错误而异常终止,或被操作系统及有终止权的进程所终止时所处的状态。

各状态之间的转换:

  1. 就绪→执行 处于就绪状态的进程,当进程调度程序为之分配了处理机后,该进程便由就绪状态转变成执行状态。
  2. 执行→就绪 处于执行状态的进程在其执行过程中,因分配给它的一个时间片已用完而不得不让出处理机,于是进程从执行状态转变成就绪状态。
  3. 执行→阻塞 正在执行的进程因等待某种事件发生而无法继续执行时,便从执行状态变成阻塞状态。
  4. 阻塞→就绪 处于阻塞状态的进程,若其等待的事件已经发生,于是进程由阻塞状态转变为就绪状态。

孤儿进程 & 僵尸进程

孤儿进程:父进程退出,子进程还在运行的这些子进程都是孤儿进程,孤儿进程将被init进程(1号进程)所收养,并由init进程对他们完成状态收集工作。

僵尸进程:进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait 获waitpid 获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中的这些进程是僵尸进程。

进程调度算法

  • 先来先服务(FCFS,first come first served):非抢占式调度算法,这是最简单的一种调度算法,比较好理解,就是根据进程到达的先后顺序执行进程,不考虑等待时间和执行时间。优点:公平,实现简单,缺点:比较有利于长作业,而不利于短作业

  • 时间片轮转(RR,Round-Robin):抢占式调度,给每个进程固定的执行时间,根据进程到达的先后顺序让进程在单位时间片内执行,执行完成后便调度下一个进程执行,适用于分时系统。优点:兼顾长短作业缺点:平均等待时间较长,上下文切换较费时

  • 短作业优先(SJF, Shortest Job First):非抢占式调度算法,对预计执行时间短的进程优先处理。对应的还有最短剩余时间优先算法,这是类似抢占式的短作业优先算法。优点:相比FCFS 算法,该算法可改善平均周转时间和平均带权周转时间,缩短进程的等待时间,提高系统的吞吐量。缺点:不利于长作业

  • 高响应比优先(HRRN,Highest Response Ratio Next):非抢占式调度算法,最高响应比是一种折中的算法,先来先服务主要考虑的是作业的等待时间而未考虑到作业的执行时间,短作业优先主要考虑的是作业的执行时间而未考虑作业等待时间。而最高响应比同时考虑到了两者,其响应比=(预估的进程执行时间+进程等待时间)/ 预估的进程执行时间,这就保证了等待时间相同的情况下,作业执行的时间越短,响应比越高,同时响应比会随着等待时间减小而变大,优先级会提高,能够避免饥饿现象,适用于批处理系统。优点:兼顾长短作业。缺点:计算响应比开销大

  • 优先级调度算法:抢占式调度算法,在进程等待队列中选择优先级最高的来执行。

  • 多级反馈队列(Multilevel Feedback Queue):抢占式调度算,这是一种将时间片轮转和优先级调度想结合的算法,把进程按优先级分成不同的队列,先按优先级调度,优先级相同的,按时间片轮转。优点:兼顾长短作业,有较好的响应时间,可行性强

死锁 & 解决死锁

产生死锁需要满足下面四个条件:

  1. 互斥条件:进程对所分配到的资源不允许其他进程访问,若其他进程访问该资源,只能等待,直至占有该资源的进程使用完成后释放该资源。
  2. 占有并等待条件:进程获得一定的资源后,又对其他资源发出请求,但是该资源可能被其他进程占有,此时请求阻塞,但该进程不会释放自己已经占有的资源。
  3. 非抢占条件:进程已获得的资源,在未完成使用之前,不可被剥夺,只能在使用后自己释放。
  4. 循环等待条件:进程发生死锁后,必然存在一个进程-资源之间的环形链。

解决死锁的方法即破坏产生死锁的四个必要条件之一,主要方法如下:

  1. 资源一次性分配,这样就不会再有请求了(破坏请求条件)。
  2. 只要有一个资源得不到分配,也不给这个进程分配其他的资源(破坏占有并等待条件)。
  3. 可抢占资源:即当进程新的资源未得到满足时,释放已占有的资源,从而破坏不可抢占的条件。
  4. 资源有序分配法:系统给每类资源赋予一个序号,每个进程按编号递增的请求资源,释放则相反,从而破坏环路等待的条件

虚拟地址 & 虚拟内存

CPU 从一个有N=pow(2,n)个地址的地址空间中生成虚拟地址,现代系统通常支持 32 位或者 64 位虚拟地址空间。一个系统还有一个物理地址空间(physical address space),对应于系统中物理内存的M 个字节。虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存,而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。

页面置换算法

当访问一个内存中不存在的页,并且内存已满,则需要从内存中调出一个页或将数据送至磁盘对换区,替换一个页,这种现象叫做缺页置换。

先进先出(FIFO)算法:置换最先调入内存的页面,即置换在内存中驻留时间最久的页面。按照进入内存的先后次序排列成队列,从队尾进入,从队首删除。特点:实现简单;性能较差,调出的页面可能是经常访问的

最近最少使用(LRU)算法:置换最近一段时间以来最长时间未访问过的页面。根据程序局部性原理,刚被访问的页面,可能马上又要被访问;而较长时间内没有被访问的页面,可能最近不会被访问。缺页时,计算内存中每个逻辑页面的上一次访问时间,选择上一次使用到当前时间最长的页面特点:可能达到最优的效果,维护这样的访问链表开销比较大当前最常采用的就是LRU算法。

最不常用算法(Least Frequently Used, LFU):缺页时,置换访问次数最少的页面,每个页面设置一个访问计数,访问页面时,访问计数加1,缺页时,置换计数最小的页面。特点:算法开销大,开始时频繁使用,但以后不使用的页面很难置换

LRU算法实现

class LRUCache {

    class Node{
        int key;
        int value;
        Node prev;
        Node next;
        public Node(){}
        public Node(int key,int value){this.key = key; this.value = value;}
    }

    private HashMap<Integer,Node> cache = new HashMap<>();
    private int size;
    private int capacity;
    private Node head,tail;

    public LRUCache(int capacity) {
        this.size = 0;
        this.capacity = capacity;
        // 使用伪头部和伪尾部结点
        head = new Node();
        tail = new Node();
        //构建双向链表
        head.next = tail;
        tail.next = head;
    }
    
    public int get(int key) {
        Node node = cache.get(key);
        if(node == null){
            return -1;
        }
        moveToHead(node);
        return node.value;
    }
    
    public void put(int key, int value) {
        Node node = cache.get(key);
        if(node == null){
            //如果key不存在,创建一个新的结点
            Node temp = new Node(key,value);
            cache.put(key,temp);
            //将最新存进来的结点移动至头部
            addToHead(temp);
            ++size;
            //如果长度超出了我们的容量,将尾部的结点删除
            if(size > capacity){
                Node tail = removeTail();
                cache.remove(tail.key);
                --size;
            }
        }else{
            //如果存在key,将原来的值覆盖掉
            node.value = value;
            moveToHead(node);
        }
    }

    private void addToHead(Node node){
        node.prev = head;
        node.next = head.next;
        head.next.prev = node;
        head.next = node;
    }

    private void removeNode(Node node){
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }

    private void moveToHead(Node node){
        removeNode(node);
        addToHead(node);
    }

    private Node removeTail(){
        Node res = tail.prev;
        removeNode(res);
        return res;
    }
}

Linux

常用指令

ls   显示文件或目录

-l 列出文件详细信息l(list)

-a 列出当前目录下所有文件及目录,包括隐藏的a(all)

mkdir 创建目录

-p 创建目录,若无父目录,则创建p(parent)

cd 切换目录

touch 创建空文件

echo 创建带有内容的文件。

cat 查看文件内容

cp 拷贝

mv 移动或重命名

rm 删除文件

-r 递归删除,可删除子目录及文件

-f 强制删除

find 在文件系统中搜索某文件

wc 统计文本中行数、字数、字符数

grep 在文本文件中查找某个字符串

rmdir 删除空目录

tree 树形结构显示目录,需要安装tree包

pwd 显示当前目录

ln 创建链接文件

more、less 分页显示文本文件内容

head、tail 显示文件头、尾内容

系统管理命令

stat 显示指定文件的详细信息,比ls更详细

who 显示在线登陆用户

whoami 显示当前操作用户

hostname 显示主机名

uname 显示系统信息

top 动态显示当前耗费资源最多进程信息

ps 显示瞬间进程状态 ps -aux

du 查看目录大小 du -h /home带有单位显示目录信息

df 查看磁盘大小 df -h 带有单位显示磁盘信息

ifconfig 查看网络情况

ping 测试网络连通

netstat 显示网络状态信息

man 命令不会用了,找男人 如:man ls

clear 清屏

alias 对命令重命名 如:alias showmeit=“ps -aux” ,另外解除使用unaliax showmeit

kill 杀死进程,可以先用ps 或 top命令查看进程的id,然后再用kill命令杀死进程。

文件权限管理

R 读数值表示为4;W 写数值表示为2 ;X 可执行数值表示为1

例如“-rw-rw-r–”:664

  • 其中第一个字符“-”表示普通文件,这个位置还可能会出现“l”链接,“d”表示目录;
  • 其中2到4字符,“rw-”表示当前所属用户的权限。 所以用数值表示为4+2=6
  • 其中5到7字符,“rw-”表示当前所属组的权限。 所以用数值表示为4+2=6
  • 其中8到10字符,“r–”表示其他用户权限。 所以用数值表示为4

sudo chmod [u所属用户 g所属组 o其他用户 a所有用户] [+增加权限 -减少权限] [r w x] 目录名 //修改权限

例如权限为“-rw-r----x” ,将权限值改为"-rwxrw-r-x":

  • sudo chmod u+x g+w o+r filename
  • sudo chmod 765 filename
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值