? 大家看过前面文章的应该都知道python中的GIL的存在,也就是多线程的时候,同一时间只能有一个线程在CPU上运行,而且是单个CPU上运行,不管你的CPU有多少核数。如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。
多进程介绍
- 进程:一个程序运行起来后,代码+用到的资源 称为进程。他是操作系统分配资源的基本单元。线程完成的多任务,进程也可以。
- 现在的电脑的CPU一般都有多个核心,在Python中可以使用 multiprocessing 包比较方便地实现将计算任务分配给多个核心,使之并行地计算以实现加速的效果。
- 进程是表示资源分配的基本单位,又是调度运行的基本单位。例如,用户运行自己的程序,系统就创建一个进程,并为它分配资源,包括各种表格、内存空间、磁盘空间、I/O设备等。所以,进程是系统中的并发执行的单位。
多进程用法
多进程实现方法
- Python中的多进程是通过multiprocessing包来实现的。
- 利用multiprocessing.Process对象来创建一个进程对象。
- 构造方法:
Process([group [, target [, name [, args [, kwargs]]]]])
- group: 线程组
- target: 要执行的方法
- name: 进程名
- args/kwargs: 要传入方法的参数
- 实例方法:
- start() :进程准备就绪,等待CPU调度。
- run():strat()调用run方法,如果实例进程时未制定传入target,这star执行t默认run()方法。
- join([timeout]):阻塞当前上下文环境的进程程,直到调用此方法的进程终止或到达指定的timeout(可选参数)。
- is_alive():返回进程是否在运行,bool类型。
- terminate():不管任务是否完成,立即停止工作进程
- 属性:
1. 常见多进程用法
-
最简单的多进程方法: from multiprocessing import Process
def fun1(name):
print('测试%s多进程' %name)
if __name__ == '__main__':
process_list = []
for i in range(5):
p = Process(target=fun1,args=('Python',))
p.start()
process_list.append(p)
for i in process_list:
p.join()
print('结束测试')
2. 类实现多进程用法
-
继承类Process方法: from multiprocessing import Process
class MyProcess(Process):
def __init__(self,name):
super(MyProcess,self).__init__()
self.name = name
def run(self):
print('测试%s多进程' % self.name)
if __name__ == '__main__':
process_list = []
for i in range(5):
p = MyProcess('Python')
p.start()
process_list.append(p)
for i in process_list:
p.join()
print('结束测试')
多进程通信
? 进程是系统独立调度核分配系统资源(CPU、内存)的基本单位,进程之间是相互独立的,每启动一个新的进程相当于把数据进行了一次克隆,子进程里的数据修改无法影响到主进程中的数据,不同子进程之间的数据也不能共享,这是多进程在使用中与多线程最明显的区别。
? 但是难道Python多进程中间难道就是孤立的吗?
? 当然不是,python也提供了多种方法实现了多进程中间的通信和数据共享(可以修改一份数据)
1. 进程队列Queue
-
queue:进程之间的数据管道,实现进程通信。 -
有点类似派一个间谍过去,时不时的往回发送情报。 from multiprocessing import Process,Queue
def fun1(q,i):
print('子进程%s 开始put数据' %i)
q.put('我是%s 通过Queue通信' %i)
if __name__ == '__main__':
q = Queue()
process_list = []
for i in range(3):
p = Process(target=fun1,args=(q,i,))
p.start()
process_list.append(p)
for i in process_list:
p.join()
print('主进程获取Queue数据')
print(q.get())
print(q.get())
print(q.get())
print('结束测试')
2. 管道Pipe
-
管道Pipe和Queue的作用大致差不多,也是实现进程间的通信。 -
有点类似量子纠缠,先设置一对纠缠粒子,把其中一个发送给子进程,然后通过量子纠缠的方式进行瞬时通信。 from multiprocessing import Process, Pipe
def fun1(conn):
print('子进程发送消息:')
conn.send('你好主进程')
print('子进程接受消息:')
print(conn.recv())
conn.close()
if __name__ == '__main__':
conn1, conn2 = Pipe()
p = Process(target=fun1, args=(conn2,))
p.start()
print('主进程接受消息:')
print(conn1.recv())
print('主进程发送消息:')
conn1.send("你好子进程")
p.join()
print('结束测试')
3. 数据共享方法Managers
进程池
总结
进程与线程区别
进程和线程分别适用于什么情况
参考
欢迎查看更多教程:
个人主页: https://weicun.gitee.io/
|