Python之进程信号量,事件,进程间通信与生产者消费者模型

# 进程锁的作用是同一时间只允许一个进程访问被锁的代码
# 信号量的作用是统一时间允许指定个数进程访问代码
# from multiprocessing import Process
# import time
# import random
#
# def func(i):
#     print("%s开始执行代码"%(i),time.time())
#     time.sleep(random.randint(1,5))
#     print("%s执行结束"%(i),time.time())
#
# # 有20个进程要执行func
# if __name__ == '__main__':
#     for i in range(1,21):
#         p = Process(target=func,args=(i,))
#         p.start()
'''
1开始执行代码 1555142395.3926342
2开始执行代码 1555142395.3946288
3开始执行代码 1555142395.445492
4开始执行代码 1555142395.4544683
5开始执行代码 1555142395.5212898
6开始执行代码 1555142395.5881112
7开始执行代码 1555142395.6200256
8开始执行代码 1555142395.64097
9开始执行代码 1555142395.6938314
10开始执行代码 1555142395.7566607
11开始执行代码 1555142395.7875812
12开始执行代码 1555142395.843428
13开始执行代码 1555142395.8703563
14开始执行代码 1555142395.9112463
15开始执行代码 1555142395.9661005
16开始执行代码 1555142396.0109806
17开始执行代码 1555142396.0558605
18开始执行代码 1555142396.0718174
19开始执行代码 1555142396.1117103
20开始执行代码 1555142396.1695824
17执行结束 1555142397.0563135
18执行结束 1555142397.0723288
3执行结束 1555142397.445812
4执行结束 1555142397.4548035
6执行结束 1555142397.5884788
9执行结束 1555142397.694322
11执行结束 1555142397.787952
14执行结束 1555142397.9116335
15执行结束 1555142397.9664843
16执行结束 1555142398.0114963
10执行结束 1555142398.75727
12执行结束 1555142398.8438897
13执行结束 1555142398.8708198
19执行结束 1555142399.112128
1执行结束 1555142399.393596
5执行结束 1555142399.5213497
7执行结束 1555142399.620567
2执行结束 1555142400.39559
8执行结束 1555142400.6415663
20执行结束 1555142401.1699862
'''
# 20个进程几乎同时开始了执行代码

# 使用信号量控制指定数量进程可以执行代码
# from multiprocessing import Process
# from multiprocessing import Semaphore
# import time
# import random
#
# def func(i,sem):
#     sem.acquire()
#     print("%s开始执行代码"%(i),time.time())
#     time.sleep(random.randint(1,5))
#     print("%s执行结束"%(i),time.time())
#     sem.release()
# # 有20个进程要执行func
# if __name__ == '__main__':
#     sem = Semaphore(4)
#     for i in range(1,21):
#         p = Process(target=func,args=(i,sem))
#         p.start()
'''
1开始执行代码 1555142606.4910986
3开始执行代码 1555142606.5210192
2开始执行代码 1555142606.5494523
4开始执行代码 1555142606.5783749
1执行结束 1555142607.4916732
5开始执行代码 1555142607.4916732
3执行结束 1555142607.521539
6开始执行代码 1555142607.521539
6执行结束 1555142608.522116
8开始执行代码 1555142608.522116
2执行结束 1555142608.5499928
7开始执行代码 1555142608.5499928
5执行结束 1555142610.4926128
9开始执行代码 1555142610.4926128
7执行结束 1555142610.5504608
10开始执行代码 1555142610.5504608
4执行结束 1555142610.5783856
11开始执行代码 1555142610.5783856
8执行结束 1555142611.5229352
12开始执行代码 1555142611.5229352
12执行结束 1555142613.523161
13开始执行代码 1555142613.523161
10执行结束 1555142613.5509596
14开始执行代码 1555142613.5509596
11执行结束 1555142614.5784695
16开始执行代码 1555142614.5784695
9执行结束 1555142615.4931543
15开始执行代码 1555142615.4931543
14执行结束 1555142617.5513644
17开始执行代码 1555142617.5513644
13执行结束 1555142618.523744
18开始执行代码 1555142618.523744
17执行结束 1555142618.551792
19开始执行代码 1555142618.551792
15执行结束 1555142619.4933243
20开始执行代码 1555142619.4933243
16执行结束 1555142619.5790558
20执行结束 1555142621.494176
18执行结束 1555142622.5248418
19执行结束 1555142623.55239
'''
# 可以看到,同时只有4个进程在运行,只有有进程退出(sem.release)后,其它进程才可以运行起来

# 事件--使用事件的set,clear配合wait方法控制进程的阻塞
# 红绿灯模型
# from multiprocessing import Process
# from multiprocessing import Event
# import random
# import time
#
# def cars(event,n):
#     while True:
#         if event.is_set():
#             print("car%s通过"%(n))
#             break
#         else:
#             print("car%s等待绿灯"%(n))
#         event.wait()
#
# def light(event):
#     while True:
#         print("绿灯亮")
#         event.set()
#         time.sleep(3)
#         event.clear()
#         print("红灯亮")
#         time.sleep(2)
#         event.set()
#
# if __name__ == '__main__':
#     event = Event()
#     p_light = Process(target=light,args=(event,))
#     p_light.start()
#     for i in range(1,21):
#         p_car = Process(target=cars,args=(event,i))
#         p_car.start()
#         time.sleep(1)
'''
绿灯亮
car1通过
car3通过
car2通过
红灯亮
car4等待绿灯
car5等待绿灯
绿灯亮
car4通过
car5通过
car6通过
car7通过
car8通过
红灯亮
car9等待绿灯
car10等待绿灯
绿灯亮
car9通过
car10通过
car11通过
car12通过
car13通过
红灯亮
car14等待绿灯
car15等待绿灯
绿灯亮
car14通过
car15通过
car16通过
car17通过
car18通过
红灯亮
car19等待绿灯
car20等待绿灯
绿灯亮
car19通过
car20通过
红灯亮
绿灯亮
红灯亮
绿灯亮
'''

# 进程间通信(IPC)-Queue(队列)
# from multiprocessing import Process
# from multiprocessing import Queue
#
# def func(q):
#     q.put(1)
#
# if __name__ == '__main__':
#     q = Queue()
#     p = Process(target=func,args=(q,))
#     p.start()
#     print(q.get()) # 输出了1

# 生产者消费者模型
# from multiprocessing import Process
# from multiprocessing import Queue
# import random
# import time
#
# def producer(q,i):
#     time.sleep(random.random())
#     q.put("第%s条消息"%(i))
#     print("生产了第%s条消息"%(i))
#
# def consumer(q,i):
#     time.sleep(random.random())
#     ret = q.get() + "被消费了"
#     print(ret)
#
# if __name__ == '__main__':
#     q = Queue()
#     for i in range(20):
#         p = Process(target=producer,args=(q,i))
#         p.start()
#     for i in range(20):
#         p = Process(target=consumer,args=(q,i))
#         p.start()
'''
生产了第3条消息
生产了第2条消息
生产了第4条消息
生产了第6条消息
生产了第7条消息
生产了第8条消息
生产了第1条消息
生产了第13条消息
生产了第0条消息
生产了第11条消息
生产了第10条消息
生产了第16条消息
生产了第5条消息
生产了第12条消息
生产了第18条消息
生产了第9条消息
生产了第19条消息
生产了第15条消息
第3条消息被消费了
第2条消息被消费了
生产了第14条消息
第4条消息被消费了
第6条消息被消费了
生产了第17条消息
第7条消息被消费了
第8条消息被消费了
第1条消息被消费了
第13条消息被消费了
第0条消息被消费了
第11条消息被消费了
第10条消息被消费了
第16条消息被消费了
第5条消息被消费了
第12条消息被消费了
第18条消息被消费了
第9条消息被消费了
第19条消息被消费了
第15条消息被消费了
第14条消息被消费了
第17条消息被消费了
'''

# 生产者生产的消息与要消费者要消费的消息对等,则没有问题,如果生产者生产的数据少于消费者要消费的数据,则整个程序会进入阻塞状态
# 如果消费者要消费的消息少于生产者生产的数据少于生产者生产的,则还有消息未被消费完,根本原因在于消费者无法感知生产者的结束
# 手动发送结束信号解决生产者消费者问题
# from multiprocessing import Process
# from multiprocessing import Queue
# import time
# import random
#
# def producer(q,n):
#     time.sleep(random.random())
#     q.put(n)
#     print("生产者生产了第%d条消息"%(n))
# def consumer(q):
#     while True:
#         time.sleep(random.random())
#         ret = q.get()
#         if ret:
#             print("消费了第%d条消息"%(ret))
#         else:break
# if __name__ == '__main__':
#     q = Queue()
#     pro_lst = []
#     for i in range(1,21):
#         pro = Process(target=producer,args=(q,i))
#         pro.start()
#         pro_lst.append(pro)
#     con = Process(target=consumer,args=(q,))
#     con.start()
#     for p in pro_lst:p.join()
#     q.put(None)
# 手动发送结束信息的方式有多少个消费者就要发送多少个结束信息

# 使用JoinableQueue解决生产者消费者问题
# from multiprocessing import Process
# from multiprocessing import JoinableQueue
# import time,random
# 
# def producer(q,n):
#     for i in range(n):
#         time.sleep(random.random())
#         q.put(n)
#         print("生产了第%d条消息"%(i))
#     q.join() # 等待队列中的数据被全部消费完才结束(即感知计数器吉减为0了)
# def consumer(q):
#     while True:
#         time.sleep(random.random())
#         ret = q.get()
#         print("消费了第%d条消息"%(ret))
#         q.task_done() # 消费一条消息计数器减1
# 
# if __name__ == '__main__':
#     q = JoinableQueue() # 可以认为内部维持着一个计数器,每放入一个数据加1
#     p = Process(target=producer,args=(q,10))
#     c = Process(target=consumer,args=(q,))
#     c.daemon = True # 消费者随着主进程代码结束而结束
#     p.start()
#     c.start()
#     p.join() # 等待生产者进程结束
# 整个流程为:生产者进程依赖于消费者取完队列中的消息而结束,消费者进程依赖于主进程代码结束而结束
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值