并发编程01

并发编程——操作系统的发展史、多道技术、进程

操作系统的发展史

1.1 穿孔卡片

  • 读取数据速度特别慢
  • CPU的利用率极低
  • 单用户(一份代码)使用

1.2 批处理

  • 读取数据速度特别慢
  • CPU利用率低
  • 联机(多份代码)使用

1.3 脱机批处理(现代操作系统的设计原理)

  • 读取速度提高
  • CPU利用率提高

多道技术(基于单核背景下产生的)

单道:一条道走到黑(串行)

比如: a,b需要使用cpu,a先使用,b等待a使用完毕后,b才能使用cpu。

多道:一条路分配着走

比如:a,b需要使用cpu,a先使用,b等待a,直到a进入“IO或执行时间过长”,a会(切换 + 保存状态),然后b可以使用cpu,待b执行遇到 “IO或执行时间过长”再将cpu执行权限交给a,直到两个程序结束

空间上的复用

多个程序使用一个CPU

时间上的复用

切换 + 保存状态

①:当执行程序遇到IO时,操作系统会将CPU的执行权限剥夺。

​ 优点:

​ CPU的执行效率高

②:当执行程序执行时间过长时,操作系统将cup的权限剥夺

​ 缺点:

​ 程序的执行效率低

并发与并行

并发:指资源有限的情况下,两者交替轮流使用资源,比如一段路同时只能过一人,A走完一段后,让给B,B走完继续给A,这样交替使用,目的是提高效率

并行:指的是两者同时执行,比如赛跑,两个人一直都在不停地往前跑

区别:

​ 并行是同时运行,只有具备多个CPU才能实现并行

​ 并发是伪并行,看起来像同时运行,单个CUP+多道技术可以实现并发(并行也属于并发)

进程

什么是进程?

进程是一个资源单位,指正在进行的一个过程或者说一个任务

进程与程序的区别

程序仅仅只是一堆代码而已, 而进程指的是程序的运行过程。

进程调度

①:先来先服务调度算法

谁先来先服务谁,待服务完毕后,再服务下一个

缺点:执行效率低

②:短作业优先调度算法

谁执行的时间越短,优先调度谁

缺点:导致执行时间长的程序,需要等待所有时间短的程序全部执行完毕后,才能执行

③:时间片轮转法

让每个进程在就绪队列中的等待时间与享受服务的时间成比例。在时间片轮转法中,需要将CPU的处理时间分成固定大小的时间片,例如,几十毫秒至几百毫秒。如果一个进程在被调度选中之后用完了系统规定的时间片,但又未完成要求的任务,则它自行释放自己所占有的CPU而排到就绪队列的末尾,等待下一次调度。同时,进程调度程序又去调度当前就绪队列中的第一个进程。

④:多级反馈队列

同步异步

同步异步都指的是“提交任务的方式”

同步(串行):

一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成,这是一种可靠的任务序列。要么成功都成功,失败都失败,两个任务的状态可以保持一致。

异步(并发):

不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也立即执行,只要自己完成了整个任务就算完成了。至于被依赖的任务最终是否真正完成,依赖它的任务无法确定,所以它是不可靠的任务序列。

阻塞与非阻塞

阻塞(等待):

凡是遇到IO都会阻塞:

​ input()

​ time.sleep(3)

​ output()

​ ……

非阻塞(不等待):

除了IO都是非阻塞

进程的三种状态

  • 就绪态
  • 运行态
  • 阻塞态

进程的两种创建方式

# 方式一:直接调用process
from multiprocessing import Process
import time


def task():
    print("start...")
    time.sleep(3)
    print("end...")


# 注意:要把创建子进程的部分放在  if __name__ == "__main__": 保护起来 否则在import时会造成无限递归
if __name__ == "__main__":
    # target=任务 ---> 创建一个子进程
    p_obj = Process(target=task)
    # start() ---> 告诉操作系统,去创建一个子进程
    p_obj.start()
    # join() ---> 告诉主进程,等待子进程结束后,再结束
    p_obj.join()
    print("正在执行当前主进程...")
    
    
# 方式二:继承 Process 类,并重写它的 run() 方法来创建进程类,程序创建 Process 子类的实例作为进程。
class MyProcess(Process):
    def run(self):
        print(f"{self.name}的子进程start...")
        time.sleep(3)
        print(f"{self.name}的子进程end...")


if __name__ == "__main__":
    list1 = []
    
    for line in range(10):
        obj = MyProcess()
        obj.start()
        list1.append(obj)
        
    for obj in list1:
        obj.join()
        
    print("主进程...")
posted @ 2019-12-06 20:07  小小小小小小小小小白  阅读(208)  评论(0编辑  收藏  举报