进程:顾名思义,运行中的程序
一、创建进程的方式:(2种)
两种方式都是利用multiprocessing模块导入Process类来实现具体方法看代码
第一种:
from multiprocessing import Process import time # 创建的子程序代码 def task(name): print('%s is running' % name) time.sleep(2) print('%s is over' % name) # 注意,在windows系统中,创建进程会将代码以模块的方式从头到尾加载一遍 # 一定要写在if __name__ == '__main__':代码块里面 # 强调:函数名一旦加括号,执行优先级最高,立刻执行 # 主程序 if __name__ == '__main__': p1 = Process(target=task, args=('egon', )) p1.start() # 告诉操作系统创建一个进程 print('主程序打印打印')
第二种:
from multiprocessing import Process import time class MyProcess(Process): def __init__(self, name): super().__init__() self.name = name # 必须写run方法 def run(self): print('%s is running' % self.name) time.sleep(1) print('%s is end' % self.name) if __name__ == '__main__': obj = MyProcess('egon') obj.start() print('主程序')
两种方法其实过程大致相同,实现方式略微有点差别
结果都是:
主进程正在运行
egon is running!
egon is end!
子进程对象.start()方法:向操作系统发出请求:说我要创建个子进程了,快帮我搞一个。
此时start处的代码相当于异步继续向下执行,执行速度肯定会快于操作系统收到请求然后选择性的创建子进程,所以主程序执行完了,子进程的代码才开始执行。
要想让子进程先执行,然后执行下面的主程序的话,可以在子进程下面来个.join(),意思是你子进程先走,我等你搞定了我再进行接下来的主进程代码!
from multiprocessing import Process import time def task(name): print('%s is running!' % name) time.sleep(2) print('%s is end!' %name) if __name__ == '__main__': p = Process(target=task, args=('egon', )) p.start() p.join() print('主进程继续运行') # 结果 egon is running! egon is end! 主进程正在运行
一次性创建多个子程序:
from multiprocessing import Process import time def task(name): print('%s正在运行。。。。。' %name) time.sleep(2) print('%s运行结束。。。。。' %name) if __name__ == '__main__': p_list = [] for i in range(1,4): p = Process(target=task, args=('进程[%s]' % i, )) p.start() p_list.append(p) for n in p_list: n.join() print('主进程继续进行!')
二、进程之间的数据是互相隔离的,无法共享
# 记住 进程与进程之间数据是隔离的!!! from multiprocessing import Process x = 100 def task(): global x x = 1 if __name__ == '__main__': p = Process(target=task) p.start() p.join() print('主',x)
三、进程之间的数据通信:
进程之间无法交互数据,因为进程与进程之间是相互隔离的,如果要实现数据的通信,可以间接的通过一些方法去实现:比如队列
队列相当于给进程间创造了一个公共管道,数据的通信通过这个管道进行。
from multiprocessing import Process,JoinableQueue import time import random def producer(name, food, q): for i in range(1,5): data = '%s<%s>' % (food, i) time.sleep(random.randint(1, 2)) q.put(data) print('[%s]造好了[%s]' % (name, data)) def consumer(name, q): while True: data = q.get() time.sleep(random.randint(1, 2)) # if data is None: break print('[%s]吃了%s' % (name, data)) q.task_done() if __name__ == '__main__': q = JoinableQueue() p1 = Process(target=producer, args=('大佬', '酸奶', q)) p2 = Process(target=producer, args=('DSB', '香蕉', q)) c2 = Process(target=consumer, args=('SSSS', q)) c1 = Process(target=consumer, args=('BBBB', q)) p1.start() p2.start() c1.daemon = True c2.daemon = True c1.start() c2.start() p1.join() p2.join() q.join() print('主程序-到此一游')
四、生产者消费者模型
这个模型实际上就是队列的应用,主要用于进程间的数据交互。一个产生数据一个拿产生的数据,实现过程就是队列。
from multiprocessing import Process,JoinableQueue import time import random def producer(name, food, q): for i in range(1, 5): data = '%s%s' % (food, i) time.sleep(random.randint(1, 2)) print('%s已经做好了%s' % (name, data)) q.put(data) def consumer(name, q): while True: data = q.get() time.sleep(random.randint(1, 2)) print('%s 消灭了一个%s' % (name, data)) q.task_done() # 每次取完数据之后,都会告诉队列一声:我这次取完了 if __name__ == '__main__': q = JoinableQueue() # 生成一个队列对象 p1 = Process(target=producer, args=('小明', '包子', q)) p2 = Process(target=producer, args=('小黄', '馒头', q)) c1 = Process(target=consumer, args=('根根', q)) c2 = Process(target=consumer, args=('矮矮', q)) p1.start() p2.start() c1.daemon = True # 守护进程,达到主进程结束,这个子进程也会一起结束 c2.daemon = True # 守护进程,达到主进程结束,这个子进程也会一起结束 c1.start() c2.start() p1.join() # 生产者完成所有生成之后才能进行下一步 p2.join() q.join() # 等待队列中的数据全部取出,才能往下走 print('主')