python进程同步控制,信号量,事件
Posted Hear7
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python进程同步控制,信号量,事件相关的知识,希望对你有一定的参考价值。
#进程同步(multiprocessing.Lock multiprocessing.Semaphore multiprocessing.Event #在计算机中,有一些硬件和软件,例如处理器,打印机,都属于竞争类资源.当有需求时,很多 #进程都有争抢这些资源,而对于这类资源,就属于临界资源.当多进程共同处理某一个数据时, # 这个数据也就属于一个临界资源.操作系统对计算机内部各种资源都使其在竞争中有序,但对数据来说,尤其是动态数据,处理是 # 就变成临界资源,需要对临界资源加以保护,否者会出现数据混乱现象 #<<<<<<锁 multiprocessing.Lock #程序实现了异步,它们之间没有顺序,一旦开启不受控制 #当多个子进程使用同一份数据资源的时候,就会引发数据安全或者顺序混乱问题 # 多进程抢占资源 # # from multiprocessing import Process # import random,time # # def func(addr): # print("我是%s"%addr) # time.sleep(random.random()) # print("谢谢") # # if __name__ == ‘__main__‘: # lst = ["湖北的",‘北京的‘,‘山西的‘,‘河北的‘] # for addr in lst: # p = Process(target=func,args=(addr,)) # p.start() # #time.sleep(2) # print(‘我选%s‘%random.choice(lst)) #结果: # 我选湖北的 $ 主进程抢 # 我是湖北的 # 我是北京的 # 我是山西的 # 我是河北的 # 谢谢 # 谢谢 # 谢谢 # 谢谢 #抢占输出资源的事情,是指多进程并发执行时,并不是一个进程执行完任务后其他进程再执行 # 使用锁维护输出资源 # from multiprocessing import Process,Lock # import time,random # # def func(addr,lock): # lock.acquire() # print("我是%s" %addr) # time.sleep(random.random()) # print("谢谢") # lock.release() # if __name__ == ‘__main__‘: # lock = Lock() # lst = ["湖北的",‘北京的‘,‘山西的‘,‘河北的‘] # for addr in lst: # p = Process(target=func,args=(addr,lock)) # p.start() # time.sleep(4) # print(" 我选%s"%random.choice(lst)) # 结果: 正常结果,输入所有人的名单,再选人 # 我是湖北的 # 谢谢 # 我是北京的 # 谢谢 # 我是山西的 # 谢谢 # 我是河北的 # 谢谢 # # # 我选山西的 #注意:使用加锁的形式确保了程序的顺序执行,但是执行又变成了串行,降低了效率,但是安全 # 模拟12306多人抢票问题 # # from multiprocessing import Process,Lock # import json # import time # def check(i): #查票 # with open(‘info‘) as f: # con = f.read() # print(‘第%s个人在查票,余票为%s‘ %(i,con)) # # # def pay(i,l): #买票 # l.acquire() # with open(‘info‘) as f: # con = int(f.read()) # time.sleep(0.01) # if con: # print(‘ 33[31m 第%s个人买到票了 33[0m‘%i) # con -= 1 # else: # print(‘ 33[032m 第%s个人没买到票 33[0m‘%i) # with open(‘info‘,"w") as f: # f.write(str(con)) # l.release() # # if __name__ == ‘__main__‘: # l = Lock() # for i in range(10): # 多用户查看票数 # p = Process(target=check,args=(i+1,)) # p.start() # for i in range(10): # 多用户并发购买票 # p_buy = Process(target=pay,args=(i+1,l)) # p_buy.start() # 加锁可以保证多个进程修改同一块数据,同时只能有一个任务可以进行修改 #即串行的修改,速度慢,但是保证了数据的安全性 #注意: #虽然可以用文件共享数据实现进程间的通信,但是效率低,需要自己加锁处理 #因此我们最好找寻一种解决方案能够兼顾: # 1、效率高(多个进程共享一块内存的数据) # 2、帮我们处理好锁问题。这就是mutiprocessing模块为我们提供的基于消息的IPC通信机制:队列和管道。 # 队列和管道都是将数据存放于内存中 # 队列又是基于(管道+锁)实现的,可以让我们从复杂的锁问题中解脱出来, # 我们应该尽量避免使用共享数据,尽可能使用消息传递和队列,避免处理复杂的同步和锁问题, # 而且在进程数目增多时,往往可以获得更好的可获展性。 #<<<<<<<<<<信号量>>>>>.. #互斥锁只允许一个线程更改数据,而信号量Semaphore是同时允许一定数量的线程更改数据 # s = Semaphore(n) # n是指初始化一把锁配n把钥匙,一个int型 # 拿钥匙锁门 s.acquire() # 还钥匙开门 s.release() # 信号量机制比锁机制多了一个计数器,这个计数器是用来记录当前剩余几把钥匙的 # 当计数器为0时,表示没有钥匙,此时acquire()处于阻塞状态 # 对于计数器来说每acquire()一次计算器内部就减1,release()一次,计数器就加1 # from multiprocessing import Process,Semaphore # import time,random # # def work(sem,i): # sem.acquire() # print(‘%s占到一个房间‘%i) # time.sleep(random.random()) # 模拟在房间中待的时间 # sem.release() # # if __name__ == ‘__main__‘: # sem = Semaphore(8) # 配四把钥匙 # lst = [] # for i in range(10): # p = Process(target=work,args=(sem,i)) # p.start() # lst.append(p) # [i.join() for i in lst] # print(">>>>>>>>>") # <<<<事件>>>>> # python线程的事件用于主线程控制其它线程的执行,事件主要提供三个方法 set,wait,clear # 事件处理的机制:is_set() 方法的值,默认为False ,那么程序执行event.wait方法时会阻塞 #如果is_set()值为True是,那么event.wait方法执行是便不阻塞 # clear()方法:将is_set()的值设置为False # set()方法:将is_set()的值设置为True # 红绿灯控制实例 from multiprocessing import Process,Event import time,random def light(e): while 1: if e.is_set(): e.clear() print(" 33[031m红灯亮了 33[0m") else: e.set() print(" 33[032m绿灯亮了 33[0m") time.sleep(2) def cars(i,e): if not e.is_set(): print("第%s辆车过去了" % i) e.wait() print("第%s辆车过去了" %i) if __name__ == ‘__main__‘: e = Event() p = Process(target=light,args=(e,)) # 红灯进程 p.start() for i in range(50): car = Process(target=cars,args=(i+1,e)) car.start() time.sleep(random.random()) # # # from multiprocessing import Process, Event # import time # import random # 亮灯和车行驶是异步的 # 亮灯的进程先开启 # is_set()刚开始默认为False # 先开始l绿灯亮,这个时候car的进程开启,is_set()为True,可以过车 # # def light(e): # while 1: # if e.is_set(): # e.clear() # print(‘ 33[31m红灯亮了 33[0m‘) # else: # e.set() # print(‘ 33[32m绿灯亮了 33[0m‘) # time.sleep(2) # # # def cars(i, e): # if not e.is_set(): # print(‘第%s辆车在等待‘ % i) # e.wait() # print(‘第%s辆车过去了‘ % i) # # # if __name__ == ‘__main__‘: # # e = Event() # tr = Process(target=light, args=(e,)) # 创建一个进程控制红绿灯 # tr.start() # # for i in range(50): # 创建50个进程代表50辆车 # car = Process(target=cars, args=(i + 1, e)) # car.start() # time.sleep(random.random()) #
以上是关于python进程同步控制,信号量,事件的主要内容,如果未能解决你的问题,请参考以下文章
Python之路(第三十八篇) 并发编程:进程同步锁/互斥锁信号量事件队列生产者消费者模型
python 管道 事件 信号量 进程池(map/同步/异步)回调函数
第34篇 通过类的方法开启子进程,以及传参,join阻塞,daemon守护进程,同步Lock,Samphore信号量,event事件