Process类参数介绍
group -------- 参数未使用, 值始终为None
target -------- 表示调用对象, 即子进程要执行的任务
args ---------- 表示调用对象的位置参数元组, args=(1,2,'hades',) 是一个元组形式,必须有逗号
kwargs ------- 表示调用对象的字典, kwargs={'name':'hades','age':18}
name --------- 为子进程的名称
Process类方法介绍
p.start() ----------------- 启动进程, 并调用该子进程中的p.run()
p.run() ------------------- 进程启动时运行的方法, 正是它去调用target指定的函数, 自定义类的类中一定要实现该方法
p.terminate() ----------- 强制终止进程p, 不会进行任何清理操作, 如果p创建了子进程, 该子进程就成了僵尸进程, 使用该方法需要特别小心这种情况.
如果p还保存了一个锁那么也将不会被释放, 进而导致死锁
p.is_alive() -------------- 判断进程是否存活, 如果p仍然运行, 返回True
p.join() ------------------- 主进程等待p子进程终止(是主进程处于等的状态,而p子进程处于运行的状态), 只能join住start开启的进程, 不能join住run开启的进程
Process类属性介绍
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字符的字符串.
这个键的用途是为涉及网络连接的底层进程间通信提供安全性,这类连接只有在具有相同的身份验证键时才能成功(了解知识点)
什么是进程
使用进程是要实现并发效果
进程就是一个正在进行/运行的程序, 换言之, 进程指的是一个程序的运行过程
程序vs进程:
程序: 只是一堆代码文件
进程: 程序运行的过程才是进程
串行: 一个任务完完整整地运行完毕, 再执行下一个任务, 按次序依次进行
判断串行的概念:
串行看起来就是一个一个运行的: 对
一个一个的运行就是串行: 错误
并发(切换+保存状态): 多个任务看起来是同时运行, 单核就可以实行并发
并行: 多个任务是真正意义上的同时运行, 只有多核才能实现并行
多道技术的产生背景: 就是想要在单核下实现并发
如何实现:
1. 空间上的复用: 将内存分为几部分, 每个部分放入一个程序的数据, 这样同一时间内存中就有了多道程序的数据, 为CPU在多个任务间切换做准备
2. 时间上的复用: 多个进程共享CPU的时间
关键点就是CPU在多个任务之间进行切换
有两种情况下会发生切换:
1. 一个任务占用CPU时间过长(没有遇到IO操作): 会降低效率
2. 一个任务在运行的过程中遇到IO操作: 可以提升效率
开启子进程的方式1
1 from multiprocessing import Process
2 import time
3
4
5 def task(name):
6 print('%s is running' % name)
7 time.sleep(3)
8 print('%s is done' % name)
9
10
11 # 在windows系统上开启子进程的操作必须放到该行代码下
12 if __name__ == '__main__':
13 p = Process(target=task, args=('子进程',)) # Process(target=task,kwargs={'name':'子进程'}) #
14 p.start() # 仅仅只是向操作系统发送一个创造子进程的信号
15 print('主')
终端打印:
开启子进程的方式2
1 from multiprocessing import Process
2 import time
3
4
5 class Myprocess(Process):
6 def __init__(self, name):
7 super().__init__()
8 self.name = name
9
10 def run(self):
11 print('%s is running' % self.name)
12 time.sleep(3)
13 print('%s is done' % self.name)
14
15
16 # 在windows系统上开启子进程的操作必须放到该行代码下
17 if __name__ == '__main__':
18 p = Myprocess('子进程')
19 p.start() # 仅仅只是向操作系统发送一个创造子进程的信号
20 p.join()
21 print('主')
终端打印:
join方法
1 from multiprocessing import Process
2 import time
3
4
5 def task(name, n):
6 print('%s is running' % name)
7 time.sleep(n)
8 print('%s is done' % name)
9
10
11 if __name__ == '__main__':
12 start = time.time()
13 p_l = []
14 for i in range(1, 4):
15 p = Process(target=task, args=('子进程%s' % i, i))
16 p_l.append(p)
17 p.start()
18
19 for p in p_l:
20 p.join()
21 stop = time.time()
22 print('主', (stop - start))
终端打印:
进程之间内存隔离
1 from multiprocessing import Process
2
3 n = 100
4
5
6 def task():
7 global n
8 n = 0
9
10
11 if __name__ == '__main__':
12 p = Process(target=task, )
13 p.start()
14 p.join()
15 print('主', n)
终端打印:
进程的PID
1 from multiprocessing import Process, current_process
2 import time, os
3
4
5 def task():
6 print('子进程[%s] 父进程<%s>' % (os.getpid(), os.getppid()))
7 time.sleep(300)
8
9
10 if __name__ == '__main__':
11 p = Process(target=task)
12 p.start()
13 print('主', os.getpid(), os.getppid())
14 time.sleep(1000)
终端打印:
进程对象其他相关的属性或方法
p.name 更改子进程的名字
1 from multiprocessing import Process
2 import time, os
3
4
5 def task():
6 print('%s is running' % os.getppid())
7 time.sleep(300)
8
9
10 if __name__ == '__main__':
11 p = Process(target=task, name='子进程1')
12 p.start()
13 print(p.name)
14 print('主')
15 time.sleep(1000)
终端打印:
terminate与is_alive
p.terminate() 关闭进程
p.is_alive() 查看进程是否存活
1 from multiprocessing import Process
2 import time, os
3
4
5 def task():
6 print('%s is running' % os.getppid())
7 time.sleep(300)
8
9
10 if __name__ == '__main__':
11 p = Process(target=task, name='子进程1')
12 p.start()
13 p.terminate()
14 time.sleep(0.1)
15 print(p.is_alive())
16 print('主')
终端打印: