1. 信号量
对于多进程来说,多个进程同时修改数据,就可能出现安全隐患,所以引入了锁,这一机制,但锁只能有一把来控制一个的开关,当你需要几把锁的时候,就可能用到信号量的概念。他是用了锁的原理,内置了一个计数器,在同一时内,只能有指定数量的进程来执行某一段被控制的代码。
import time,random from multiprocessing import Process,Semaphore def singing(i,sem): ‘‘‘ :param i: 随机生成20个数的值 :param sem:生成的信号量 :return:None ‘‘‘ sem.acquire()#获得锁 print(‘%s is coming ‘%i) time.sleep(random.randint(10,20))#随机在10秒至20秒中停顿 print(‘%s is going out‘%i) sem.release()#释放锁 if __name__ == ‘__main__‘: sem = Semaphore(4)#生成4个锁 for i in range(20): p = Process(target=singing,args=(i,sem)) p.start()
2. 事件
事件是通过一个信号来控制多个进程的同时执行或阻塞,当一个事件被创建的时候默认是阻塞状态,但不影响进程的执行,当遇到 even.wait() 方法时,才会阻塞。
# set 和 clear # 分别用来修改一个事件的状态 True或者False # is_set 用来查看一个事件的状态 # wait 是依据事件的状态来决定自己是否在wait处阻塞 # False阻塞 True不阻塞
下面是一个红绿灯的问题。
import time import random from multiprocessing import Event,Process def cars(e,i): ‘‘‘ 一个判断车是否通过的函数 :param e: 传入一个事件 :param i: 生成的车几 :return: None ‘‘‘ if not e.is_set(): print(‘\033[0;31;40mcar %s 在等待~\033[0m‘%i) e.wait() print(‘\033[32;40mcar %s 通过~\033[0m‘%i) def light(e): ‘‘‘ 控制红绿灯的切换 :param e: 传入事件 :return: None ‘‘‘ while True: if e.is_set(): e.clear() print(‘\033[31m红灯亮了\033[0m‘) time.sleep(3) else: e.set() print(‘\033[32m绿灯亮了\033[0m‘) time.sleep(5) if __name__ == ‘__main__‘: e = Event() traffic = Process(target=light,args=(e,)) traffic.start() time.sleep(1) for i in range(random.randint(5,10)): car = Process(target=cars,args=(e,i)) car.start() time.sleep(random.randint(1,3))
3. 队列
队列 Queue 中只有少数几个方法,
# put 当队列满的时候阻塞等待队列有空位置 # get 当队列空的时候阻塞等待队列有数据 # full empty 不完全准确
full 和 empty 不准一原因在于,如果队列回答主程序时,同时进程又对队列进行了操作,这个就会造成数据的错误。
4. 用 JoinableQueue 来处理生产者和消费者模型
import time import random from multiprocessing import Process,JoinableQueue def producer(name,food,q): for i in range(4): time.sleep(random.randint(1,3)) f = ‘%s生产了%s%s‘%(name,food,i) print(f) q.put(f) q.join() # 阻塞 直到一个队列中的所有数据 全部被处理完毕 def consumer(q,name): while True: food = q.get() print(‘\033[31m%s消费了%s\033[0m‘ % (name,food)) time.sleep(random.randint(1,3)) q.task_done() # count - 1 if __name__ == ‘__main__‘: q = JoinableQueue(20) p1 = Process(target=producer,args=(‘eli‘,‘dumpling‘,q)) p2 = Process(target=producer, args=(‘tom‘,‘noodle‘, q)) c1 = Process(target=consumer, args=(q,‘mike‘)) c2 = Process(target=consumer, args=(q,‘johan‘)) p1.start() p2.start() c1.daemon = True # 设置为守护进程 主进程中的代码执行完毕之后,子进程自动结束 c2.daemon = True c1.start() c2.start() p1.join() p2.join() # 感知一个进程的结束
觉得最好的点就是用到了守护进程(当主进程的程序执行完成时,子进程也随之结束)。
原文地址:https://www.cnblogs.com/YS-0717/p/9742137.html
时间: 2024-10-13 09:05:24