名词解释:
进程: 一个具有一定独立功能的程序关于某个数据集合的一次运行活动,是系统进行资源分配和调度运行的基本单位
1. 并行
在某个*时间点*,两件或两件以上的事件(任务)同时执行.
比如说,有三条车道,某个时刻,有三辆车同时在这三个车道上跑.
2. 并发
在某个*时间段*内,两件或两件以上的事件(任务),轮流交替使用某一资源,目的是提高效率.
比如说,有一条单行车道,允许一辆车通过,有A,B两辆车要通过单行道,那么只有当A或B先通过后,另一辆车才能启动通过该单行道.
并行并发区别:
并行是从微观上,在某一具体的时间点,有不同的程序在执行,这就要求系统又多个处理器(多核).
并发是从宏观上,在一个时间段上来看,是同时执行的;但从微观上来说,相当于串行(宏观上*并行*,微观上*串行*)
3. 同步
一个任务的完成需要依赖另一个任务,只有被依赖的任务完成后,依赖的任务才能算完成.这两个任务,要么都成功,要么都失败,状态可以保持一致.
举例:
A和B两个任务,A任务执行过程中需要调用B任务,调用B任务后,需要等待B的响应结果(B给出明确的反馈返回给A),如果A没有收到B的响应,A会一直等待,不会继续向下执行,只有B返回响应结果给A后,A任务才会继续向下执行.
4. 异步
一个任务的完成不需要等待被依赖的任务完成,只是通知被依赖的任务需要做什么,通知完之后,依赖任务会继续向下执行,自己完成了,整个任务就算完成.
举例:
A任务执行过程中可能需要调用B,C,D等其他任务,在调用B,C,D等其他任务后,A不需要等待它们的返回结果,只是简单的调用,其他任务的执行结果或情况与A无关,A只是把消息或指令传给它们,A会继续向下执行,A执行完成,任务就算完成了.
银行的转账系统,对数据库的保存操作等等,会使用同步交互操作,其余情况优先使用异步交互操作
Java中的同步和异步两种交互方式
同步交互: 指发送一个请求,需要等待返回,然后才能发送下一个请求,有个等待过程;
异步交互: 指发送一个请求,不需要等待返回,随时可以发送下一个请求,即不需要等待.
阻塞,非阻塞:
概念: 程序等待调用结果时的状态
5. 阻塞
调用结果返回之前,执行线程会被挂起,不释放cpu执行权,线程不能做其他事情,只能等待,只有等到调用结果返回了,才能接着往下执行.
6. 非阻塞
在没有获取调用结果时,不是一直等待,线程可以往下执行,如果是同步的,通过轮询的方式检查调用结果有没有返回,如果是异步的,会通知回调.
7. 守护进程
运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对某个用户程序提供服务。
执行代码
1. 建立开启子进程两种方式
from multiprocessing import Process import os import time # 开启子进程的两种方式 # 方式1 def run(num): print('子进程%s执行,进程id:%s' % (num, os.getpid())) time.sleep(1.5) print('子进程%s结束,进程id:%s' % (num, os.getpid())) if __name__ == '__main__': print('父进程执行,进程id:%s' % os.getpid()) for i in range(3): p = Process(target=run, args=(i,)) p.start() print('父进程结束,进程id:%s' % os.getpid()) # 进程代码逐行读取,主进程不会等待子进程结束(主进程,子进程异步) # 执行结果 父进程执行,进程id:4472 子进程0执行,进程id:4473 父进程结束,进程id:4472 子进程1执行,进程id:4474 子进程2执行,进程id:4475 子进程0结束,进程id:4473 子进程1结束,进程id:4474 子进程2结束,进程id:4475 # 方式2,继承Process类 class MyProcess(Process): def __init__(self, name): super().__init__() self.name = name def run(self): print('子进程%s,进程id:%s' % (self.name, os.getpid())) if __name__ == '__main__': print('父进程开始') p = MyProcess('jason') p.start() # 自动触发调用类中的run方法 p.join() print('父进程结束') # 执行结果 父进程开始 子进程jason,进程id:4486 父进程结束
2. 进程的常用方法
# p.start(); p.join(); p.is_alive(); p.terminate() def func(): print('测试进程中常用方法') if __name__ == '__main__': p = Process(target=func,) p.start() # 开启一个进程 p.terminate() # 杀掉一个进程 print(p.is_alive()) # 判断进程是否还存活 p.join() # 等待进程结束,再继续向下执行;异步变同步 print(p.is_alive()) print('父进程结束') # 执行结果 True False 父进程结束
3. 进程的属性
# p.name; p.pid; p.daemon = True(将进程p变为守护进程,daemon默认为False) def func(): n = 1 while n: time.sleep(1) print('测试进程的属性--%s' % n) n += 1 if __name__ == '__main__': p = Process(target=func,) p.daemon = True # 子进程变为守护进程; 守护进程会随着父进程的结束而结束; 守护进程不能创建子进程 p.start() print(p.name) # 获取子进程名 print(p.pid) # 获取进程ID time.sleep(5) print('父进程结束') # 执行结果 Process-1 4512 测试进程的属性--1 测试进程的属性--2 测试进程的属性--3 测试进程的属性--4 父进程结束