并发编程
并发编程
系统发展史
【操作系统的发展过程】:
1. 人工操作方式
2. 脱机输入输出技术
3. 批处理技术
4. 多道程序设计技术
5. 分时、实时系统
6. 通用操作系统
7. 微机操作系统
8. 网络操作系统
9. 分布式操作系统
【 操作系统的概念】:
操作系统是一组控制和管理计算机硬件和软件资源、合理组织计算机的工作流程,以及方便用户的程序的集合。
【操作系统的作用】:
(1)OS作为用户与计算机硬件系统之间的接口
(2)OS作为计算机系统资源的管理者
(3)OS用作扩充机器
【操作系统的分类】:
1. 单用户操作系统
2. 批处理操作系统
(1) 单道批处理系统
(2) 多道批处理系统
3. 分时操作系统
(1) 单道分时系统
(2) 具有“前台”和“后台”的分时系统
(3) 多道分时系统
4. 实时操作系统
5. 网络操作系统
多道技术
-
产生的背景:cpu在执行一个任务的过程中,若需要操作硬盘,则发送操作硬盘的指令,指令一旦发出,硬盘上的机械手臂滑动读取数据到内存中,这一段时间,cpu需要等待,时间可能很短,但对于cpu来说已经很长很长,长到可以让cpu做很多其他的任务,如果我们让cpu在这段时间内切换到去做其他的任务,这样cpu不就充分利用了吗。这正是多道技术产生的技术背景
-
多道技术就是多个程序,多道技术的实现是为了解决多个程序竞争或者说共享一个资源的伊欧徐调度问题,解决的办法就是多路复用,多路复用分为时间上的复用和空间上的复用
空间上的复用:将内存分为多部份,每部分每个部分放入一个程序,这样,同一时间内存中就有了躲到程序
时间上的复用:当一个程序在等待I/O时,另一个程序可以使用cpu,如果内存中可以同时存放足够多的作业,cpu利用率可以接近100%,类似于我们学的统筹的方法。(操作系统采用了多道技术后,可以控制进程的切换,或者说进程之间去争抢cpu的执行权限。这种切换不仅会在一个进程遇到io时进行,一个进程占用cpu时间过长也会切换,或者说被操作系统夺走cpu的执行权限)
空间上复用最大的问题
程序之间的内存必须分割,这种分割需要在硬件层面实现,由操作系统控制,如果不分割,一个程序可以访问另一个程序
利弊问题: 安全性差,比如你的qq程序可以访问操作系统的内存,这意味着你的qq可以拿到操作系统的所有权限。 稳定性差,某个程序崩溃时有可能把别的程序的内存也给回收了,比方说把操作系统的内存给回收了,则操作系统崩溃 切换(CPU)分为两种情况 * 当一个程序遇到IO操作的时候,操作系统会剥夺该程序的CPU执行权限 作用:提高了CPU的利用率 并且也不影响程序的执行效率 * 当一个程序长时间占用CPU的时候,操作吸引也会剥夺该程序的CPU执行权限 弊端:降低了程序的执行效率(原本时间+切换时间)
进程的理论
程序和进程的区别:
程序时存放在硬盘上的代码,这个只有去执行的时候才会有用,是死的。但是进程表示程序在执行的过程。
进程调度:
-
先来先服务调度算法:就是谁先来先服务谁,这样的话对长作业有益,对短作业无益。
-
短作业优先算法:对短作业有利,多长作业无益
-
时间片轮转法和多级反馈队列
进程运行的三种状态
同步异步与阻塞非阻塞
-
同步与异步
"""描述的是任务的提交方式""" 同步:任务提交之后,原地等待任务的返回结果,等待的过程中不做任何事(干等) 程序层面上表现出来的感觉就是卡住了 异步:任务提交之后,不原地等待任务的返回结果,直接去做其他事情 我提交的任务结果如何获取? 任务的返回结果会有一个异步回调机制自动处理
-
阻塞非阻塞
"""描述的程序的运行状态""" 阻塞:阻塞态 非阻塞:就绪态、运行态 理想状态:我们应该让我们的写的代码永远处于就绪态和运行态之间切换
最理想的组合就是
异步非阻塞
进程的两种方式
multiprocess.process:process模块是一个创建进程的模块,借助这个模块,就可以完成进程的创建。
强调: 1. 需要使用关键字的方式来指定参数 2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号 参数介绍: 1 group参数未使用,值始终为None 2 target表示调用对象,即子进程要执行的任务 3 args表示调用对象的位置参数元组,args=(1,2,'egon',) 4 kwargs表示调用对象的字典,kwargs={'name':'egon','age':18} 5 name为子进程的名称
from multiprocessing import Process import time def task(name): print('%s is running'%name) time.sleep(3) print('%s is over'%name) if __name__ == '__main__': # 1 创建一个对象 p = Process(target=task, args=('jason',)) # 容器类型哪怕里面只有1个元素 建议要用逗号隔开 # 2 开启进程 p.start() # 告诉操作系统帮你创建一个进程 异步 print('主') # 第二种方式 类的继承 from multiprocessing import Process import time class MyProcess(Process): def run(self): print('hello bf girl') time.sleep(1) print('get out!') if __name__ == '__main__': p = MyProcess() p.start() print('主')
总结:
""" 创建进程就是在内存中申请一块内存空间将需要运行的代码丢进去 一个进程对应在内存中就是一块独立的内存空间 多个进程对应在内存中就是多块独立的内存空间 进程与进程之间数据默认情况下是无法直接交互,如果想交互可以借助于第三方工具、模块 """
join()方法
join是让主进程等待子进程代码运行结束之后,再继续运行。不影响其他子进程的执行
from multiprocessing import Process
import time
def task(name, n):
print('%s is running'%name)
time.sleep(n)
print('%s is over'%name)
if __name__ == '__main__':
start_time = time.time()
p_list = []
for i in range(1, 4):
p = Process(target=task, args=('子进程%s'%i, i))
p.start()
p_list.append(p)
for p in p_list:
p.join()
print('主', time.time() - start_time)
进程之间的数据间隔
from multiprocessing import Process
import time
def task(name, n):
print('%s is running'%name)
time.sleep(n)
print('%s is over'%name)
if __name__ == '__main__':
start_time = time.time()
p_list = []
for i in range(1, 4):
p = Process(target=task, args=('子进程%s'%i, i))
p.start()
p_list.append(p)
for p in p_list:
p.join()
print('主', time.time() - start_time)