系统


1 进程、线程

参考资料戳这里

1.1 区别

  • 进程是资源分配的最小单位,线程是CPU调度的最小单位

  • 一个程序中至少有一个进程,而一个进程中至少有一个线程

    浏览器是多进程的,渲染进程是多线程的

  • 进程是运行中的程序,线程是进程内部的一个执行序列

  • 进程资源独占,线程资源共享;

1.2 绝妙例子——说明进程线程关系及特性(进程-火车,线程-车厢)

来源:知乎

  • 线程在进程下行进:单纯的车厢无法运行

  • 一个进程可以包含多个线程:一辆火车可以有多个车厢

  • 不同进程间数据很难共享,同一进程下不同线程间数据很易共享:一辆火车上的乘客很难换到另外一辆火车,比如站点换乘,A车厢换到B车厢很容易

  • 进程要比线程消耗更多的计算机资源:采用多列火车相比多个车厢更耗资源

  • 进程间不会相互影响,一个线程挂掉大多数时候将导致整个进程挂掉

    • 一列火车出事故不会影响到另外一列火车

    • 但是如果一列火车上中间的一节车厢着火了,很可能将影响到所有车厢
      例外情况:java中一个线程爆栈了或者OOM(Out Of Memory,内存溢出)了,其他线程不会受影响。例如坐票车厢特别拥挤,但不会影响到卧铺车厢

  • 进程可以拓展到多机,线程最多适合多核:不同火车可以开在多个轨道上,同一火车的车厢不能在行进的不同的轨道上

  • 一个进程上的多个线程,在多核处理器系统中能并行执行一个列车上的多个车厢的事务可以由多位乘务员(多核)同时进行处理

  • 进程使用的内存地址可以上锁,即一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。(比如火车上的洗手间)-"互斥锁"

  • 进程使用的内存地址可以限定使用量:比如火车上的餐厅,最多只允许多少人进入,如果满了需要在门口等,等有人出来了才能进去-“信号量”

1.3 进程、线程状态

  • 5大线程状态
    在这里插入图片描述

    • 所有函数
      start()-开始 yield()-让步 resume():重新开始 notify():通知 suspend():挂起、延缓 synchronized():同步

    • 1、新建状态:新创建一个线程对象。

    • 2、就绪状态(start、yield):线程对象创建后,其他线程调用了该对象的 start() 方法。该状态的线程位于“可运行的线程池”中,变得可运行,只等待获取CPU的使用权。即在就绪状态的进程除了CPU之外,其他的运行所需资源都已全部获得。

    • 3、运行状态:就绪状态的线程获取了CPU,执行程序代码。

    • 4、阻塞状态(join):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。

    • 5、死亡状态:线程执行完了或者因异常退出了 run() 方法,该线程结束生命周期。

  • 3大进程状态

  • 在这里插入图片描述

    • 1、就绪态:进程已经具备运行条件,但是CPU还没有分配过来。

    • 2、运行态:进程占用CPU,并在CPU上运行。

    • 3、阻塞态:进程因等待某件事发生而暂时不能运行

🚩补充:sleep wait join yield区别

  • sleep:Thread类的方法,让出cpu调度,不释放锁,调用后进入阻塞态
  • yield:Thread类的方法,让出cpu调度,让同优先级的线程有执行的机会,如果没有则立刻继续执行。调用后进入可运行态
  • wait:Object类的方法,让出cpu调度,释放锁,调用后进入休眠态(notify / interrupt()后进入阻塞态)
  • join:特殊的wait,让出cpu调度,释放锁,调用后进入阻塞态,当前运行线程调用另一个线程的join方法,当前线程进入阻塞状态直到另一个线程运行结束再继续执行。

1.4 进程、线程的同步

  • 进程同步:信号量、管程、消息传递

    • 1、信号量用于进程间传递信号的一个整数值。两个或多个进程可以通过简单的信号进行合作,一个进程可以被迫在某一位置停止,直到它接收到一个特定的信号。

    在信号量上只有三种操作可以进行:初始化,P操作和V操作,P操作(递减操作)可以用于阻塞一个进程,V操作(增加操作)可以用于解除阻塞一个进程。

    • 2、管程(只允许一个线程进入):管程是由一个或多个过程、一个初始化序列和局部数据组成的软件模块,原理如下:
    • 局部数据变量只能被管程的过程访问,任何外部过程都不能访问。
    • 一个进程通过调用管程的一个过程进入管程。
    • 在任何时候,只能有一个进程在管程中执行,调用管程的任何其他进程都被阻塞,以等待管程可用。
    • 3、消息传递(生产者-消费者):进程间进程消息传递所需要的最小操作
    • 一个进程以消息的形式给另一个指定的目标进程发送消息;
    • 进程通过执行receive原语接收消息,receive原语中指明发送消息的源进程和消息。
  • 线程同步:互斥量、信号量、事件、临界区
    两个或多个共享关键资源的线程的并发执行。应该同步线程以避免关键的资源使用冲突。

    • 互斥量(Mutex):采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问。比如Java中的synchronized关键词和各种Lock 都是这种机制。

    • 信号量(Semphares) :它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量

    • 事件(Event) :通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操作

    • 临界区(Critical Section):保证在某一时刻只有一个线程能访问数据的简便办法。在任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么在有一个线程进入后,其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享资源的目的。

1.5 进程、线程的死锁

一组竞争系统资源或相互通信的进程相互的永久阻塞

  • 进程 / 线程产生死锁的四个必要条件(须同时满足):

    • (1) 互斥条件:一个资源每次只能被一个进程使用。

    • (2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

    • (3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能被强行剥夺。

    • (4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

    • 解读东西一次只能一个人用(1),大家排队排成一圈(4),不插队(3),不离队(2)

  • 解决死锁的四种方式

    • 鸵鸟策略:不采取任务措施。因为解决死锁问题的代价很高,因此鸵鸟策略这种不采取任务措施的方案会获得更高的性能。

    • 死锁检测与死锁恢复:检测主要是查看当前是否出现了环路等待;恢复可以通过杀死进程或者利用回滚

    • 死锁预防:在程序运行之前破坏发生死锁的条件,预防发生死锁
      比如说破坏环路等待:可以给资源统一编号,进程只能按编号顺序来请求资源。

    • 死锁避免 :使用银行家算法,假设给进程分配资源,看能不能找到一个安全序列,如果系统处于不安全状态,不一定会发生死锁;但是死锁时,系统一定处于不安全状态


2 IO多路复用

2.1 select、poll、epoll 复用方式

  1. select==>时间复杂度O(n)
    它仅仅知道了,有I/O事件发生了,却并不知道是哪那几个流(可能有一个,多个,甚至全部),我们只能无差别轮询所有流,找出能读出数据,或者写入数据的流,对他们进行操作。所以select具有O(n)的无差别轮询复杂度,同时处理的流越多,无差别轮询时间就越长。

  2. poll==>时间复杂度O(n)
    poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态, 但是它没有最大连接数的限制,原因是它是基于链表来存储的.

  3. epoll==>时间复杂度O(1)
    epoll可以理解为event poll,不同于忙轮询和无差别轮询,epoll会把哪个流发生了怎样的I/O事件通知我们。所以我们说epoll实际上是事件驱动(每个事件关联上fd)的,此时我们对这些流的操作都是有意义的。(复杂度降低到了O(1))

  • select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。

2.2 epoll 机制底层数据结构,为什么能够做到O(1)复杂度(待补充


3 Linux 常用命令🌈

  • 目录切换 cd
  • 目录查看 ls [-al]
  • 目录操作【增,删,改,查】

    创建目录【增】 mkdir
    删除目录或文件【删】rm
    目录修改【改】mvcp
    搜索目录【查】find

4 常见调度算法

  1. 先来先服务(FCFS)调度算法:先到先得
    既可以用于作业调度也可以用于进程调度。
  2. 短作业优先(SJF)调度算法:快的先来
    从就绪队列中选择一个估计运行时间最短的进程,将处理机分配给它,使之立即执行,直到完成或发生某事件而阻塞时,才释放处理机。
  3. 优先级调度算法
  4. 高响应比优先调度算法:等的越久、要求服务时间越短的先来
    在这里插入图片描述
  5. 时间片轮转调度算法:先到先得,且限时
    也是先来先服务的原则,但仅能运行一个时间片,如100ms。在使用完一个时间片后,即使进程并未完成其运行,它也必须释放出(被剥夺)处理机给下一个就绪的进程,而被剥夺的进程返回到就绪队列的末尾重新排队,等候再次运行。
  6. 多级反馈队列调度算法(集合了前几种算法的优点)
    时间片轮转调度算法和优先级调度算法的综合和发展
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值