multiprocessing模块
解释:综合的处理进程的包
multiprocess模块下的Process模块:和创建进程相关
创建一个进程
# 创建一个进程from multiprocessing import Process # 导入创建进程模块def func(): # 定义一个函数 print('我是一个进程')
if __name__ =='__main__': p = Process(target=func) # 创建一个进程对象p = Process(target=func),target:目标函数名 p.start() # 知道执行start才有了进程# 结果# 我是一个进程
证明创建一个进程的方法
import osfrom multiprocessing import Process # 导入创建进程模块def func(): # 定义一个函数 print('子进程:', os.getpid()) print('我是一个进程')
if __name__ =='__main__': p = Process(target=func) # 创建一个进程对象p = Process(target=func),target:目标函数名 print('主进程', os.getpid()) p.start() # 知道执行start才有了进程 print('主进程', os.getpid())# 结果# 主进程 23756# 主进程 23756# 子进程: 17900# 我是一个进程
上程序运行方法异步程序
import os # 1from multiprocessing import Process # 2def func(): # 3 print('子进程:', os.getpid()) print('我是一个进程')
if __name__ =='__main__': p = Process(target=func) # 4 print('主进程', os.getpid()) # 5 p.start() # 6 解释:只是告知操作系统我要创建程序(至于操作系统做不做我们无法控制)PS:异步 print('主进程', os.getpid()) # 7# 运行方法见标号
异步进程传参
# 异步进程传参import osfrom multiprocessing import Processdef func(exes): print('我是一个%s'%exes)if __name__ =='__main__': p = Process(target=func, args=('name',)) # 注意进程传参必须是传一个元组,即时只有一个值也要写成(123,)形式 print('我是第一顺序执行者') p.start()# 结果:# 我是第一顺序执行者# 我是一个name# PS这是一个异步程序
join介绍(阻塞)PS:主进程会阻塞在jion出等待子进程运行结束
# join介绍(阻塞)from multiprocessing import Processdef func(exes): print('我是一个%s'%exes)if __name__ =='__main__': p = Process(target=func, args=('name',)) # 注意进程传参必须是传一个元组,即时只有一个值也要写成(123,)形式 p.start() p.join() # 调用join方法:实际是一个阻塞,只有子进程结束才能继续执行:实际是变成同步程序了 print('我是第一顺序执行者') # 结果:# 我是一个name# 我是第一顺序执行者# PS加上join变成同步程序
PS:在Windows操作系统中,创建进程的语句必须放在 if name =='main':下面
开启多个子进程
开启多进程方法(可for循环开启多个进程)
# 开启多进程方法import osfrom multiprocessing import Processdef func(): print('子进程%s的主进程是%s' % (os.getpid(), os.getppid()))if __name__ =='__main__': p1 = Process(target=func) p2 = Process(target=func) p3 = Process(target=func) p4 = Process(target=func) p1.start() p2.start() p3.start() p4.start() print('------主进程%s-------'% os.getpid())
# 结果:# ------主进程2104-------# 子进程13440的主进程是2104# 子进程7576的主进程是2104# 子进程11600的主进程是2104# 子进程14832的主进程是2104
证明进程杂乱的方法
# 证明进程杂乱的方法import timeimport osfrom multiprocessing import Processdef func(i): time.sleep(1) print('%d 子进程%s的主进程是%s' % (i, os.getpid(), os.getppid()))if __name__ =='__main__': for i in range(10): p = Process(target=func, args=(i,)) p.start() print('------主进程%s-------' % os.getpid())
# 结果:# ------主进程12556-------# 0 子进程23168的主进程是12556# 2 子进程22832的主进程是12556# 1 子进程15976的主进程是12556# 3 子进程14344的主进程是12556# 4 子进程8216的主进程是12556# 8 子进程22960的主进程是12556# 6 子进程17812的主进程是12556# 5 子进程22932的主进程是12556# 9 子进程4696的主进程是12556# 7 子进程14492的主进程是12556# 子进程的运行顺序是杂乱无章的
控制先输出子进程再输出主进程方法
import timeimport osfrom multiprocessing import Processdef func(i): time.sleep(1) print('%d 子进程%s的主进程是%s' % (i, os.getpid(), os.getppid()))if __name__ =='__main__': p_lst = [] for i in range(10): p = Process(target=func, args=(i,)) p.start() p_lst.append(p) # 创建一个列表,将所有子进程地址装入列表中 for j in p_lst: j.join() print('------主进程%s-------' % os.getpid())
# 结果:# 3 子进程17612的主进程是23516# 2 子进程18616的主进程是23516# 1 子进程16812的主进程是23516# 0 子进程21592的主进程是23516# 5 子进程23480的主进程是23516# 4 子进程18064的主进程是23516# 6 子进程16284的主进程是23516# 8 子进程4524的主进程是23516# 7 子进程21924的主进程是23516# 9 子进程13000的主进程是23516# ------主进程23516-------# 控制先运行子进程再运行主进程方法
创建进程的其他方法class方法
# 创建进程的其他方法class方法import osfrom multiprocessing import Processclass MyProcess(Process): # PS:必须创建一个类(可以叫任何名字)但必须继承Process类 def __init__(self, arg1, arg2, arg3): # 传进子进程的方法 super().__init__() # PS:继承父类(Process)的init方法 self.arg1 = arg1 self.arg2 = arg2 self.arg3 = arg3 def run(self): # PS:必须有一个run方法 print('子进程:{} 参数是{} {} {}'.format(os.getpid(), self.arg1, self.arg2, self.arg3)) self.work() # 在子进程中调用work方法的方法 def work(self): print('我是work方法', os.getpid())
if __name__ == '__main__': p = MyProcess(1, 2, 3) # 传参方法 p.start() # 默认调用run方法 p.work() # work直接在主进程中调用,并没有在子进程中执行 是同步 print('主进程%s' % os.getpid())# 结果:# 我是work方法 6220# 主进程6220# 子进程:18236 参数是1 2 3# 我是work方法 18236
# 使用时注意:实例化MyProcess得到一个对象# 使用对象调用start方法# 传参直接在实例化对象的时候传参
守护进程daemon
定义:守护进程会随着主进程的代码执行结束而结束,不等待其他子进程结束;
如果行等待子进程完成(在主进程最后加join方法);
正常的子进程没有执行完的时候主进程要一直等着。
守护进程
import timefrom multiprocessing import Processdef func(): while True: time.sleep(1) print('过了一秒')if __name__ == '__main__': p = Process(target=func) p.daemon = True # 一定在开启进程之前设置 p.start() for i in range(100): time.sleep(0.1) print('*' * i)# 注意# 守护进程要在start之前设置# 守护进程中不能再开启子进程
进程的其他方法\
进程两方法p.is_alive()/p.terminate()
# p.is_alive() # 判断进程是否还活着True代表进程还在,False代表进程不在了# p.terminate() # 结束一个进程,但是这个进程不会立即被杀死(异步操作)import timefrom multiprocessing import Processdef func(): print('子进程开始') time.sleep(5) print('子进程结束')
if __name__ == '__main__': p = Process(target=func) p.start() print(p.is_alive()) # 判断进程是否还活着True代表进程还在,False代表进程不在了 time.sleep(1) p.terminate() # 结束一个进程,但是这个进程不会立即被杀死(异步操作) print(p.is_alive())
进程两属性name/pid
# name:查看进程名字\为进程名重命名# pid:查看进程id# 函数中使用import timefrom multiprocessing import Processdef func(): print('子进程开始')
if __name__ == '__main__': p = Process(target=func) p.start() print(p.name, p.pid) p.name = '重命名进程名' print(p.name)# 结果:# Process-1 16876# 重命名进程名# 子进程开始
# 类中使用class MyProcess(Process): def run(self): print('子进程开始', self.name, self.pid)
if __name__ == '__main__': p = MyProcess() p.start()# 结果# 子进程开始 MyProcess-2 13684
锁Lock
作用:就是在并发编程中,保证数据安全
定义锁和使用锁
from multiprocessing import Locklock = Lock() # 实例化一个锁lock.acquire() # 需要锁==拿钥匙lock.release() # 释放锁==还钥匙
使用锁
from multiprocessing import Lockfrom multiprocessing import Process
def func(k, lock): lock.release() print(k) lock.acquire()
if __name__ == '__main__': lock = Lock() for i in range(10): p = Process(target=func, args=(i, lock)) p.start()
信号量Semaphore
信号量应用
import timeimport randomfrom multiprocessing import Processfrom multiprocessing import Semaphore # 导入信号量
def toilet(i, sem): sem.acquire() # 需要锁==拿钥匙 print('%d进厕所' % i) time.sleep(random.randint(1, 5)) print('%d出厕所' % i) sem.release() # 释放锁==还钥匙if __name__ == '__main__': sem = Semaphore(4) # 实例化信号量并定义钥匙数量 for i in range(10): p = Process(target=toilet, args=(i, sem)) p.start()
事件Event
事件基础
# 事件基础from multiprocessing import Event # 导入事件e = Event() # 实例化一个事件e.set() # 将标志变成非阻塞e.wait() # 刚实例化出的一个事件对象,默认的信号是阻塞信号e.clear() # 将标志又变成阻塞
PS:e.is_set() # 是否阻塞 True就是非阻塞, False就是阻塞\
红绿灯事件
import timeimport randomfrom multiprocessing import Eventfrom multiprocessing import Process
def traffic_car(e): # 控制红绿灯 while True: if e.is_set(): time.sleep(3) print('红灯亮') e.clear() # 绿变红 else: time.sleep(3) print('绿灯亮') e.set() # 红变绿def car(i, e): e.wait() print('%s车通过' % i)if __name__ == '__main__': e = Event() # 立一个红绿灯 tra = Process(target=traffic_car, args=(e,)) # 实例化一个进程 tra.start() # 启动一个进程来控制红绿灯 for i in range(100): if i % 6 == 0: time.sleep(random.randint(1, 3)) car_lll = Process(target=car, args=(i, e)) # 实例化一辆车 car_lll.start() # 启动车辆
队列Queue
1、进程之间通信,可以使用multiprocessing的Queue模块
2、队列有两种创建方式,第一种不传参数,这种队列没有长度限制,第二种传参数,创建一个有最大长度限制的队列q = Queue(3)
3、提供两种重要方法:put get
4、qsize 有的操作系统会报错,有时不准(查看队列大小)
5、通过队列可以实现主进程与子进程的通信, 子进程与子进程之间的通信
队列简单使用
from multiprocessing import Queue # 引用队列q = Queue() # 实例化队列q.put(1) # 往队列放数据print(q.get()) # 在队列中取数据
主进程与子进程之间的通信
from multiprocessing import Queuefrom multiprocessing import Processdef q_put(q): q.put('hello')if __name__ == '__main__': q = Queue() p = Process(target=q_put, args=(q,)) p.start() print(q.get())# 结果:# hello
子进程与子进程之间的通信
from multiprocessing import Queuefrom multiprocessing import Processdef q_put(q): q.put('hello')def q_get(q): print(q.get())if __name__ == '__main__': q = Queue() p = Process(target=q_put, args=(q,)) p.start() p2 = Process(target=q_get, args=(q,)) p2.start()# 结果:# hello
以上就是本次分享的全部内容,现在想要学习编程的小伙伴指路微信公众号-Python编程学习圈,更多python干货分享!