进程
一、进程
1.进程的创建
导入进程包
通过进程类创建进程对象
启动进程执行任务
2.代码演示
import time import multiprocessing # sing def sing(): for i in range(3): print("sing……") time.sleep(2) # dance def dance(): for i in range(3): print("dance……") time.sleep(2) if __name__ == "__main__": #创建进程 sing_process = multiprocessing.Process(target = sing) dance_process = multiprocessing.Process(target = dance) #启动进程 sing_process.start() dance_process.start()
3.参数说明
Process(group=None, target=None, name=None, args=(), kwargs={}) """ 参数说明: 1 group——参数未使用,值始终为None 2 target——表示调用对象,即子进程要执行的任务 3 args——表示调用对象的位置参数元组 4 kwargs——表示调用对象的字典 5 name——为进程的名称 """
4.当process参数为字典或者元组时
import time import multiprocessing # sing def sing(num, name): for i in range(num): print("sing……") time.sleep(0.5) # dance def dance(num,name): for i in range(num): print("dance……") time.sleep(0.5) if __name__ == "__main__": #创建进程 sing_process = multiprocessing.Process(target = sing,args = (3,'aaa')) dance_process = multiprocessing.Process(target = dance,kwargs = {'name':'aaa','num':2}) #启动进程 sing_process.start() dance_process.start()
5.获取进程编号
1、os.getpid():获取当前进程的编号
2、os.getppid():获取父进程的编号
import time import multiprocessing import os # sing def sing(num, name): print("sing进程编号:", os.getpid()) print("sing父进程:", os.getppid()) for i in range(num): print(name + " sing……") time.sleep(0.5) # dance def dance(num, name): print("dance进程编号:", os.getpid()) print("dance父进程:", os.getppid()) for i in range(num): print(name + " dance……") time.sleep(0.5) if __name__ == "__main__": print("主进程id", os.getpid()) # 创建进程 sing_process = multiprocessing.Process(target=sing, args=(3, 'aaa')) dance_process = multiprocessing.Process(target=dance, kwargs={'name': 'aaa', 'num': 2}) # 启动进程 sing_process.start() dance_process.start()
6.注意(守护进程)
默认情况下,主进程会在所有子进程都执行完毕后,才会关闭
主进程一结束,子进程也要跟着结束。(守护进程)
守护进程:守护进程会在主进程代码执行结束后就终止,守护进程内无法再开启子进程,否则抛出异常
例如:如果我们有两个任务需要并发执行,那么开一个主进程和一个子进程分别去执行就ok了,如果子进程的任务在主进程任务结束后就没有存在的必要了,那么该子进程应该在开启前就被设置成守护进程。主进程代码运行结束,守护进程随即终止;
from multiprocessing import Process import time import random def task(name): print('%s is piaoing' %name) time.sleep(random.randrange(1,3)) print('%s is piao end' %name) if __name__ == '__main__': p=Process(target=task,args=('egon',)) p.daemon=True #一定要在p.start()前设置,设置p为守护进程,禁止p创建子进程,并且父进程代码执行结束,p即终止运行 p.start() print('主') #只要终端打印出这一行内容,那么守护进程p也就跟着结束掉了
7.Process()常用方法
join方法:
import time from multiprocessing import Process def one(name): print("My name is", name) time.sleep(2) print("This is one") def two(name): print("My name is", name) time.sleep(2) print("This is two") if __name__ == '__main__': p_one = Process(target=one, args=("J",)) p_two = Process(target=two, args=("M",)) p_one.start() p_one.join() # 主线程要等待func_one终止,才继续往下走,则p_one执行完了才会执行p_two p_two.start()
8、进程池
进程池常用方法
代码演示:
from multiprocessing import Pool import time import os def action(*args,**kwargs): print(args,' 当前进程:',os.getpid()) print(kwargs) time.sleep(3) if __name__ == '__main__': #创建包含 4 条进程的进程池 pool = Pool(processes=4) # 将action分3次提交给进程池 pool.apply_async(action) pool.apply_async(action, ('aaa', )) pool.apply_async(action, ('bbb', )) pool.apply_async(action, kwds={'name': 'ccc'}) pool.close() pool.join() ''' () 当前进程: 11448 {} ('aaa',) 当前进程: 18192 {} ('bbb',) 当前进程: 17228 {} () 当前进程: 12220 {'name': 'ccc'} '''
9、进程通信
当有某一个全局的变量,给各个进程使用,如果不合理安排,那么就会造成运算结果的不唯一性。所以,务必要加入进程的通信机制,使得各个进程之间能够协调配合。
在进程通信当中,最为常用的东西就是:Queue。顾名思义,它是一个队列。具体来说,是多进程的安全队列。
代码演示:
import multiprocessing import time # 写入数据 def write_data(queue): for i in range(10): if queue.full(): print("队列已经满了") break queue.put(i) time.sleep(0.2) print(i) # 读取数据 def read_data(queue): while True: # 加入数据从队列取完了,那么跳出循环 if queue.qsize() == 0: print("队列已经空了") break value = queue.get() print(value) if __name__ == '__main__': # 创建消息队列 queue = multiprocessing.Queue(5) # 创建写入数据的进程 write_process = multiprocessing.Process(target=write_data, args=(queue,)) # 创建读取数据的进程 read_process = multiprocessing.Process(target=read_data, args=(queue,)) # 启动进程 write_process.start() # 主进程等待写入进程执行完成以后代码再继续往下执行 write_process.join() read_process.start()