进程的概念:(Process)

进程就是正在运行的程序,它是操作系统中,资源分配的最小单位.

资源分配: 分配的是cpu和内存等物理资源

进程号是进程的唯一标识

同一个程序执行两次之后是两个进程

进程和进程之间的关系: 数据彼此隔离,通过 socket 通信

并行和并发

并行(Parallelism)和并发(Concurrency)是计算机领域中常用的概念,描述了多任务执行的不同方式。

并行指的是同时执行多个任务,即多个任务在同一时刻开始并且同时进行。在并行执行中,任务被分配给多个处理单元(如多个 CPU 核心),每个处理单元独立执行自己的任务,从而加快整体的处理速度。并行执行的任务之间可能存在依赖关系,但它们可以在不同的处理单元上独立执行,不会相互影响。

并发指的是多个任务在宏观上似乎同时进行,但在微观上是交替执行的。在并发执行中,多个任务按照一定的调度策略交替执行,每个任务在一段时间内运行一部分,然后切换到另一个任务。并发执行通常通过时间片轮转或者优先级调度等方式来实现,使得多个任务共享系统资源并且看起来同时进行。

可以将并行看作是多个任务在同一时刻真正同时执行,而并发则是多个任务在宏观上看起来同时进行,但在实际执行过程中存在交替和并行执行的情况。

需要注意的是,并行和并发并不完全相同,尽管它们经常一起使用。并行通常用于利用多核处理器或分布式系统的性能,实现任务的加速。而并发更多地涉及任务之间的交替执行和资源共享,它可以用于实现高效的多任务处理和提高系统的响应性。

在实际应用中,使用并行和并发的方式取决于具体的需求和问题。有时候需要通过并行来提高计算速度和处理能力,有时候需要通过并发来实现资源的高效利用和任务的快速响应。

cpu 的进程调度方法

CPU 的进程调度方法是操作系统决定哪个进程在何时执行的算法。以下是一些常见的 CPU 进程调度方法

  1. 先来先服务(FCFS):按照进程到达 CPU 的先后顺序进行调度。当一个进程开始执行后,直到它完成或阻塞才会切换到下一个进程。
  2. 最短作业优先(SJF):选择预计执行时间最短的进程进行调度。这种调度方法可以最大程度地减少平均等待时间,但可能导致长作业被饥饿。
  3. 优先级调度:为每个进程分配优先级,优先级高的进程优先执行。可以通过静态优先级(提前指定)或动态优先级(根据进程行为和状态动态调整)来实现。
  4. 轮转调度(Round Robin):每个进程被分配一个时间片(时间片大小固定),按顺序执行,当时间片用完后切换到下一个进程。这种调度方法可以确保公平性,但可能导致上下文切换频繁。
  5. 最高响应比优先(HRRN):根据响应比选择下一个执行的进程,响应比定义为(等待时间 + 服务时间)/ 服务时间。这种调度方法可以在一定程度上避免长作业被饥饿。
  6. 多级反馈队列调度:将进程划分为多个队列,每个队列有不同的优先级和时间片大小。进程在队列之间移动,根据优先级和时间片大小的不同,实现灵活的调度。

以上是一些常见的 CPU 进程调度方法,每种调度方法都有其优势和限制,并且适用于不同的场景和需求。实际的操作系统通常会结合多种调度方法,以在不同的情况下提供较好的性能和用户体验。

总结:

越是时间长的,cpu分配的资源越少,优先级靠后

越是时间短的,cpu分配的资源越多

进程三状态图

进程详解_非阻塞

(1)就绪 (Ready) 状态

      只剩下 CPU 需要执行外,其他所有资源都已分配完毕 称为就绪状态。

(2)执行 (Running) 状态

      cpu 开始执行该进程时称为执行状态。

(3)阻塞 (Blocked) 状态

      由于等待某个事件发生而无法执行时,便是阻塞状态,cpu 执行其他进程.例如,等待 I/O 完成 input、申请缓冲区不能满足等等。 

进程详解_优先级_02

同步 异步 / 阻塞 非阻塞

官方概念:

  1. 同步:同步是指在发起一个操作后,必须等待该操作完成后才能继续执行下一个操作。在同步模式下,程序会阻塞等待操作的完成,只有当操作返回结果后才能继续执行后续代码。同步操作是按顺序逐步执行的,每个操作都要等待前一个操作完成。
  2. 异步:异步是指发起一个操作后,不需要等待该操作完成,而是可以继续执行后续的操作。在异步模式下,程序可以立即执行后续代码,而不必等待操作的结果返回。异步操作通常会通过回调函数、事件或者轮询等方式来处理操作的结果。
  3. 阻塞:阻塞是指在执行一个操作时,调用方会被挂起,直到操作完成或达到某个条件才能继续执行。在阻塞模式下,程序会一直等待操作的结果返回,期间无法进行其他操作。
  4. 非阻塞:非阻塞是指在执行一个操作时,调用方可以立即返回,而无需等待操作的完成。在非阻塞模式下,程序会立即执行后续代码,而不必等待操作的结果。非阻塞操作通常会通过轮询或回调等方式来查询操作的状态或处理操作的结果。

白话文

场景在多任务当中

同步:必须等我这件事干完了,你在干,只有一条主线,就是同步

异步:没等我这件事情干完,你就在干了,有两条主线,就是异步

阻塞:比如代码有了input,就是阻塞,必须要输入一个字符串,否则代码不往下执行

非阻塞:没有任何等待,正常代码往下执行.

同步阻塞: 效率低,cpu 利用不充分

异步阻塞: 比如 socketserver, 可以同时连接多个,但是彼此都有 recv

同步非阻塞: 没有类似 input 的代码,从上到下执行.默认的正常情况代码

异步非阻塞: 效率是最高的 ,cpu 过度充分,过度发热 液冷

守护进程

可以给子进程贴上守护进程的名字,该进程会随着主进程代码执行完毕而结束 (为主进程守护)

  1. 守护进程会在主进程代码执行结束后就终止
  2. 守护进程内无法再开启子进程,否则抛出异常(了解)

锁(Lock)

lock.acquire() # 上锁

lock.release() # 解锁

同一时间允许一个进程上一把锁 就是 Lock

加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改,即串行的修改,没错,速度是慢了,但牺牲速度却保证了数据安全。

同一时间允许多个进程上多把锁 就是 [信号量Semaphore]

信号量是锁的变形: 实际实现是 计数器 + 锁,同时允许多个进程上锁  

# 互斥锁 Lock : 互斥锁就是进程的互相排斥,谁先抢到资源,谁就上锁改资源内容,为了保证数据的同步性

# 注意: 多个锁一起上,不开锁,会造成死锁.上锁和解锁是一对.

事件(Event)

# 阻塞事件 :

e = Event() 生成事件对象e    

e.wait() 动态给程序加阻塞 , 程序当中是否加阻塞完全取决于该对象中的 is_set() [默认返回值是False]

   # 如果是 True  不加阻塞

   # 如果是 False 加阻塞

# 控制这个属性的值

   # set() 方法     将这个属性的值改成 True

   # clear() 方法   将这个属性的值改成 False

   # is_set() 方法  判断当前的属性是否为 True  (默认上来是 False )

进程间通信 IPC

# IPC Inter-Process Communication

# 实现进程之间通信的两种机制:

   # 管道 Pipe

   # 队列 Queue

# put() 存放

# get() 获取

# get_nowait() 拿不到报异常

# put_nowait() 非阻塞版本的put

q.empty()      检测是否为空  (了解)

q.full()     检测是否已经存满 (了解)

生产者与消费者模型

进程详解_非阻塞_03