什么是信号量(multiprocess.Semaphore)

互斥锁同时只允许一个线程更改数据,而信号量semaphore是同时允许一定数量的线程更改数据.

假设商场里有4个迷你唱吧 ,所以通过同时可以进去4个人,如果来了五个人就要在外面等等,等到有人出来才能再进去玩.

实现:

信号量同步基于内部计数器,每次用一次acquire(),计数器减1,每次调用一次release(),计数器加1 ,当计数器为0 时,acquire()调用被阻塞,,信号量和进程池的概念很像,但是也要区分开,信号量设计到加锁的概念.

一套资源 同一时间 只能被n个人访问

from multiprocessing import Process,Semaphore
import time,random
def ktv(i,sem):
sem.acquire() #获取钥匙
print('%s 走进ktv'%i)
time.sleep(random.randint(1,5))
print('%s 走出ktv'%i)
sem.release() #释放钥匙.
if __name__ == '__main__':
sem = Semaphore(2) #ktv 里只有2个位置,限定进程的访问量。
for i in range (6): #六个人来访问
p =Process(target=ktv, args=(i,sem)) #实例化一个子进程.
p.start()#

结果 :同时允许两个人进入。

 走进ktv
走进ktv
走出ktv
走进ktv
走出ktv
走进ktv
走出ktv
走进ktv
走出ktv
走进ktv
走出ktv
走出ktv
sem =Semaphore()
sem.acquire()
print("第一把钥匙 ")
sem.acquire()
print("第二把钥匙 ")
sem.acquire()
print("第三把钥匙 ")
sem.acquire()
print("第四把钥匙 ")
sem.acquire()
print("第五把钥匙 ")

结果 (只能获取到四把钥匙.)

第一把钥匙
第二把钥匙
第三把钥匙
第四把钥匙

事件 --multiprocess.Event

Python 线程 的事件用于主线程控制其他线程的执行,事件的主要提供了三个方法set ,wait ,clear。

事件处理的机制,全局定义了一个 ‘Flag’ ,如果flag的值为false,那么程序执行event.wait方法时就会阻塞,如果 flag 值为True,那么

event.wait 方法时不在阻塞

clear: 将flag 设置为False

set :将 flag 设置为True

通过一个信号 来控制多个进程 同时执行或者阻塞

from multiprocessing import Event

一个信号可以使所有的进程接触阻塞

一个世界被创建之后,默认是阻塞状态

from multiprocessing import Event
e =Event() #创建一个世界
print(e.is_set())#查看一个事件的状态,默认是阻塞状态。 #结果为False
e.set() #将这个事件状态改为True
print(e.is_set())#结果为True
e.wait()#是根据e.is_set()的值来决定是否阻塞的.
print() #打印出来 结果为123435
e.clear() #将这个事件的状态改为False
print(e.is_set())#False
e.wait()#等待事件的信号被变成 True
print('*'*)

set 和clear

分别用来修改一个事件的状态True或者False

is_set 是用来查看事件的状态

wait是依据事件的状态来决定自己是否在wait处阻塞

  #False阻塞  , True 不阻塞.

# 红绿灯事件
import time
import random
from multiprocessing import Event,Process
def cars(e,i):
if not e.is_set():
print('car%i在等待'%i)
e.wait() # 阻塞 直到得到一个 事件状态变成 True 的信号
print('\033[0;32;40mcar%i通过\033[0m' % i) def light(e):
while True:
if e.is_set():
e.clear()
print('\033[31m红灯亮了\033[0m')
else:
e.set()
print('\033[32m绿灯亮了\033[0m')
time.sleep() if __name__ == '__main__':
e = Event()# 创建事件对象
traffic = Process(target=light,args=(e,)) #创建traffice 子进程
traffic.start()#启动子进程
for i in range():
car = Process(target=cars, args=(e,i))#创建一个car的子进程
car.start()
time.sleep(random.random())

队列和管道

import time
import random
from multiprocessing import Process,Queue
def consumer(q,name):
while True:
food = q.get()
if food is None:
print('%s获取到了一个空'%name)
break
print('\033[31m%s消费了%s\033[0m' % (name,food))
time.sleep(random.randint(,)) def producer(name,food,q):
for i in range():
time.sleep(random.randint(,))
f = '%s生产了%s%s'%(name,food,i)
print(f)
q.put(f) if __name__ == '__main__':
q = Queue()
p1 = Process(target=producer,args=('Egon','包子',q))
p2 = Process(target=producer, args=('wusir','泔水', q))
c1 = Process(target=consumer, args=(q,'alex'))
c2 = Process(target=consumer, args=(q,'jinboss'))
p1.start()
p2.start()
c1.start()
c2.start()
p1.join()
p2.join()
q.put(None)
q.put(None)
import time
import random
from multiprocessing import Process,JoinableQueue
def consumer(q,name):
while True:
food = q.get()
print('\033[31m%s消费了%s\033[0m' % (name,food))
time.sleep(random.randint(,))
q.task_done() # count - def producer(name,food,q):
for i in range():
time.sleep(random.randint(,))
f = '%s生产了%s%s'%(name,food,i)
print(f)
q.put(f)
q.join() # 阻塞 直到一个队列中的所有数据 全部被处理完毕 if __name__ == '__main__':
q = JoinableQueue()
p1 = Process(target=producer,args=('Egon','包子',q))
p2 = Process(target=producer, args=('wusir','泔水', q))
c1 = Process(target=consumer, args=(q,'alex'))
c2 = Process(target=consumer, args=(q,'jinboss'))
p1.start()
p2.start()
c1.daemon = True # 设置为守护进程 主进程中的代码执行完毕之后,子进程自动结束
c2.daemon = True
c1.start()
c2.start()
p1.join()
p2.join() # 感知一个进程的结束 # 在消费者这一端:
# 每次获取一个数据
# 处理一个数据
# 发送一个记号 : 标志一个数据被处理成功 # 在生产者这一端:
# 每一次生产一个数据,
# 且每一次生产的数据都放在队列中
# 在队列中刻上一个记号
# 当生产者全部生产完毕之后,
# join信号 : 已经停止生产数据了
# 且要等待之前被刻上的记号都被消费完
# 当数据都被处理完时,join阻塞结束 # consumer 中把所有的任务消耗完
# producer 端 的 join感知到,停止阻塞
# 所有的producer进程结束
# 主进程中的p.join结束
# 主进程中代码结束
# 守护进程(消费者的进程)结束

Day 38 Semaphore ,Event ,队列的更多相关文章

  1. python 多线程中的同步锁 Lock Rlock Semaphore Event Conditio

    摘要:在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lo ...

  2. python类库32[多进程同步Lock+Semaphore+Event]

    python类库32[多进程同步Lock+Semaphore+Event]   同步的方法基本与多线程相同. 1) Lock 当多个进程需要访问共享资源的时候,Lock可以用来避免访问的冲突. imp ...

  3. python第五十一天----线程,Event,队列

    进程与线程的区别: 线程==指令集,进程==资源集  (线程集) 1.同一个进程中的线程共享内存空间,进程与进程之间是独立的 2.同一个进程中的线程是可以直接通讯交流的,进程与间通讯必需通过一个中间的 ...

  4. Python学习---同步条件event/队列queue1223

    写在前面: 在使用这些共享API的时候,我们要注意以下几点: 在UNIX平台上,当某个进程终结之后,该进程需要被其父进程调用wait,否则进程成为僵尸进程(Zombie).所以,有必要对每个Proce ...

  5. python lock, semaphore, event实现线程同步

    lock 机制不管你是java, C#, 还是python都是常用的线程同步机制, 相比较C# 的锁机制, python的加锁显得比较简单, 直接调用threading 标准库的lock 就可以了. ...

  6. 扯扯python的多线程的同步锁 Lock RLock Semaphore Event Condition

    我想大家都知道python的gil限制,记得刚玩python那会,知道了有pypy和Cpython这样的解释器,当时听说是很猛,也就意味肯定是突破了gil的限制,最后经过多方面测试才知道,还是那德行… ...

  7. python并发编程-多线程实现服务端并发-GIL全局解释器锁-验证python多线程是否有用-死锁-递归锁-信号量-Event事件-线程结合队列-03

    目录 结合多线程实现服务端并发(不用socketserver模块) 服务端代码 客户端代码 CIL全局解释器锁****** 可能被问到的两个判断 与普通互斥锁的区别 验证python的多线程是否有用需 ...

  8. TI-RTOS 之 事件同步(Event, 类似semaphore)

    TI-RTOS 之 事件同步(Event, 类似semaphore) Event 是类似Semaphore的存在,官方如下描述: SYS/BIOS events are a means of comm ...

  9. Semaphore 和 Mutex

    mutex和semaphore有什么区别呢? mutex是用作互斥的,而semaphore是用作同步的. 也就是说,mutex的初始化一定是为1,而semaphore可以是任意的数, 所以如果使用mu ...

随机推荐

  1. MongoDB的基本shell操作(三)

    mongodb_server_ Installer.bat @echo offecho 正在安装服务MongoDB...start cmd /k "cd/d C:\Program Files ...

  2. 757A Gotta Catch Em' All!

    A. Gotta Catch Em' All! time limit per test 1 second memory limit per test 256 megabytes input stand ...

  3. Debian 采用 iso 镜像作为 apt 源

    1.将N个debian-506-amd64-DVD-N.iso存放于本地或其他媒介内,本例是放在本机/iso/目录下2.创建N个挂载点目录 如下: debian:~#mkdir –r /media/d ...

  4. python常用模块及面向对象(一)

    目录: 常用模块之time模块 常用模块之random模块 常用模块之os模块 常用模块之sys模块 常用模块之subprocess模块 常用模块之json模块 常用模块之pickle模块 常用模块之 ...

  5. QQ绝招

    1.让QQ头像永远在前 打开"个人设定"窗口,然后在自己的昵称前点一下鼠标,再按空格键插入一两个空格(不能太多了,要不然昵称就不能完整显示了),然后点击"修改" ...

  6. 2018.10.22 bzoj1742: Grazing on the Run 边跑边吃草(区间dp)

    传送门 区间dp入门题. 可以想到当前吃掉的草一定是一个区间(因为经过的草一定会吃掉). 然后最后一定会停在左端点或者右端点. f[i][j][0/1]f[i][j][0/1]f[i][j][0/1] ...

  7. Python特殊方法

    # __slots__如果要限制添加的属性,例如,Student类只允许添加 name.gender和score 这3个属性,就可以利用Python的一个特殊的__slots__来实现. # __sl ...

  8. EF生成的SQL语句执行顺序问题。

    //实体被更改后,再做删除,EF只生成删除语句 //实体删除后再更改,EF报错 //添加语句会再,更改,删除后执行,更AddObject位置无关 //一个实体多个字段被改,只会生成一句update / ...

  9. IntelliJ IDEA 2017版 spring-boot使用Spring Data JPA搭建基础版的三层架构

    1.配置环境pom <?xml version="1.0" encoding="UTF-8"?> <project xmlns="h ...

  10. 山东省第七届ACM竞赛 J题 Execution of Paladin (题意啊)

    题意:鱼人是炉石里的一支强大种族,在探险者协会里,圣骑士有了一张新牌,叫亡者归来,效果是召唤本轮游戏中7个已死鱼人.如果死掉的不足7个,那么召唤的数量就会不足7. 鱼人有很多,下面的4个是: 寒光智者 ...