并发: 指应用能够交替执行不同的任务
并行: 指应用能够同时执行不同的任务
同步: 所谓同步就是一个任务的完成需要依赖另一个任务时, 只有等待被依赖的任务完成后, 依赖的任务才能算完成, 这是一种可靠的任务序列, 要么都成功, 要么都失败, 两个任务的状态可以保持一致.
异步: 所谓异步是不需要等待被依赖的任务完成, 知识通知被依赖的任务要完成什么工作, 依赖的任务也立即执行, 只要自己完成了整个任务就算完成了, 至于被依赖的任务最重是否真正完成, 依赖它的任务无法确定, 所以他是不可靠的任务序列
阻塞和非阻塞这两个概念与程序 (线程) 等待消息通知 (无所谓同步或者异步) 时的状态有关. 也就是阻塞与非阻塞主要是程序 (线程) 等待消息通知时的状态角度来说的
process 模块
是一个创建进程的模块, 借助这个模块, 可以完成进程的创建
Process([group [, target [, name [, args [, kwargs]]]]]), 由该类实例化得到的对象, 表示一个子进程中的任务(尚未启动)
强调:
1. 需要使用关键字的方式来指定参数
2. args 指定的为传给 target 函数的位置参数, 是一个元组形式, 必须有逗号
参数介绍:
group 参数未使用, 值始终为 None
target 表示调用对象, 即子进程要执行的任务
args 表示调用对象的位置参数元组, args=(1,2,'egon',)
kwargs 表示调用对象的字典, kwargs={'name':'egon','age':18}
name 为子进程的名称
方法介绍:
p.start(): 启动进程, 并调用该子进程中的 p.run()
p.run(): 进程启动时运行的方法, 正是它去调用 target 指定的函数, 我们自定义类的类中一定要实现该方法
p.terminate(): 强制终止进程 p, 不会进行任何清理操作, 如果 p 创建了子进程, 该子进程就成了僵尸进程, 使用该方法需要特别小心这种情况. 如果 p 还保存了一个锁那么也将不会被释放, 进而导致死锁
p.is_alive(): 如果 p 仍然运行, 返回 True
p.join([timeout]): 主线程等待 p 终止(强调: 是主线程处于等的状态, 而 p 是处于运行的状态).timeout 是可选的超时时间, 需要强调的是, p.join 只能 join 住 start 开启的进程, 而不能 join 住 run 开启的进程
属性介绍
p.daemon: 默认值为 False, 如果设为 True, 代表 p 为后台运行的守护进程, 当 p 的父进程终止时, p 也随之终止, 并且设定为 True 后, p 不能创建自己的新进程, 必须在 p.start()之前设置
p.name: 进程的名称
p.pid: 进程的 pid
p.exitcode: 进程在运行时为 None, 如果为 - N, 表示被信号 N 结束(了解即可)
p.authkey: 进程的身份验证键, 默认是由 os.urandom()随机生成的 32 字符的字符串. 这个键的用途是为涉及网络连接的底层进程间通信提供安全性, 这类连接只有在具有相同的身份验证键时才能成功(了解即可)
在 Windows 操作系统中由于没有 fork(linux 操作系统中创建进程的机制), 在创建子进程的时候会自动 import 启动它的这个
文件, 而在 import 的时候又执行了整个文件. 因此如果将 process()直接写在文件中就会无限递归创建子进程报错. 所以
必须把创建子进程的部分使用 if __name__ =='__main__' 判断保护起来, import 的时候 , 就不会递归运行了.
使用 process 模块创建进程
在一个 python 进程中开启子进程, start 方法和并发效果
在 python 中创建第一个子进程
- import tme
- from multiprocessing import Process
- def f(name):
- print('hello',name)
- print('我是子进程')
- if __name__ == 'main':
- p = Process(target = f,args = ('bob',))
- p.start()
- time.sleep(1)
- print('执行主进程的内容了')
查看主进程和子进程的进程号
- impert os
- from multiprocessing import Process
- def f(x):
print('子进程 id:'os.getpid(), 父进程 id:',os.getppid())
- return x*x
- if __name__ == 'main':
- print('主进程 id:',os.getpid())
- p_lst = []
- for i in range(5):
- p = Process(target = f , args = (i,))
- p.start()
多个进程同时运行(子进程的执行顺序不是根据启动顺序决定的)
- import time
- from multiprocessing import Prcess
- def f(name):
- print('hello',name)
- time.sleep(1)
- if__name__=='__main__':
- p_lst = []
- for i in range(5):
- p = Process(target = f,args = (i,))
- p.start()
多个进程同时进行, 再谈 join 方法(1)
- import time
- from multiprocessing import Process
- def f(name)
- print('hello',name)
- time.sleep(1)
- if__name__=='__main__':
- p_lst = []
- for i in range(5):
- p = Process(target = f,args = ('bob',))
- p.start()
- p_lst.append(p)
- p.join()
- #[p.join() for p in p_lst]
- print('父进程在执行')
多个进程同时运行, 再谈 join 方法(2)
- import time
- from multiprocessing import Process
- def f(name):
- print('hello', name)
- time.sleep(1)
- if __name__ == '__main__':
- p_lst = []
- for i in range(5):
- p = Process(target=f, args=('bob',))
- p.start()
- p_lst.append(p)
- # [p.join() for p in p_lst]
- print('父进程在执行')
除了原生类开启进程的方法, 还有一种以继承 Process 类的形式开启进程的方式
- import os
- from mulitprocessing import Process
- class MyProcess(Process):
- def __init__(self,name):
- super(MyProcess,self).__init__()
- self.name = name
- def run(self):
- print(os.getpid())
- print('%s 正在和女主播聊天'% self.name)
- if__name__ == '__main__'
- p1 = MyProcess('zhangmincong')
- P2 = MyProcess('duanpengpeng')
- p3 = MyProcess('zhaozhenyu')
- p1.start()
- p2.start()
- p3.start()
- p1.join()
- p2.join()
- p3.join()
- print('主线程')
进程之间的数据隔离问题
- from multiprocessing import Process
- def work():
- global n
- n=0
- print('子进程内:',n)
- if __name__ == '__main__':
- n = 100
- p=Process(target=work)
- p.start()
- print('主进程内:',n)
守护进程
会随着主进程的结束而结束
主进程创建守护进程
其一: 守护进程会在主进程代码执行结束后就终止
其二: 守护进程内无法再开启子进程, 否则抛出异常: AssertionError: daemonic processes are not allowed to have children
- import os
- import time
- from multiprocessing import Process
- class Myprocess(Process):
- def __init__(self,person):
- super().__init__()
- self.person = person
- def run(self):
- print(os.getpid(),self.name)
- print('%s 正在和女主播聊天' %self.person)
- p=Myprocess('哪吒')
- p.daemon=True #一定要在 p.start()前设置, 设置 p 为守护进程, 禁止 p 创建子进程, 并且父进程代码执行结束, p 即终止运行
- p.start()
- time.sleep(10) # 在 sleep 时查看进程 id 对应的进程 ps -ef|grep id
- print('主')
- from multiprocessing import Process
- def foo():
- print(123)
- time.sleep(1)
- print("end123")
- def bar():
- print(456)
- time.sleep(3)
- print("end456")
- p1=Process(target=foo)
- p2=Process(target=bar)
- p1.daemon=True
- p1.start()
- p2.start()
- time.sleep(0.1)
- print("main-------")# 打印该行则主进程代码结束, 则守护进程 p1 应该被终止.# 可能会有 p1 任务执行的打印信息 123, 因为主进程打印 main---- 时, p1 也执行了, 但是随即被终止.
来源: http://www.bubuko.com/infodetail-2735654.html