什么是信号量(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. 将php数据下载csv文件

    <?php $sales = array( array( 'Northeast', '2005-01-01', '2005-02-01', 12.54 ), array( 'Northwest' ...

  2. spring框架之依赖注入(DI)

    1. IOC和DI的概念 * IOC -- Inverse of Control,控制反转,将对象的创建权反转给Spring!! * DI -- Dependency Injection,依赖注入,在 ...

  3. 用python做数值计算

    http://sebug.net/paper/books/scipydoc/scipy_intro.html http://www.cnblogs.com/weilq/p/3432817.html h ...

  4. 菜刀连接webshell

    中国菜刀,一个非常好用而又强大的webshell,它可不是用来切菜的做饭的道具哦,是一款专业的网站管理软件,大小只有300多KB,真是小巧实用啊!不过被不法分子利用到,就是一个黑站的利器了.我记得以前 ...

  5. python基础之删除文件及删除目录的方法-乾颐堂

    下面来看一下python里面是如何删除一个文件及文件夹的~~ 首先引入OS模块 import os 删除文件: os.remove() 删除空目录: os.rmdir() 递归删除空目录: os.re ...

  6. QFileInfo

    https://www.cnblogs.com/findumars/p/10247573.html

  7. 一篇文章Tornado快速入门

    Tornado是一个PythonWeb框架.一个异步网络库.通过使用非阻塞网络I/O,Tornado能够处理数以千计的连接,这意味着对于实时Web服务来说,Tornado是一个理想的Web框架. 作为 ...

  8. spring的IOC/DI功能实践

    一.写在前面: 做这个Demo主要是为了能够更好的理解Spring的原理,看再多的文章,听再多的讲解最终都最好自己去实现一遍,可以将Spring的功能分块实现,最终自然比较容易将各个功能组合起来. 这 ...

  9. pytest 入门及运行

    关于pytest的入门教程,官网及网上已经很多了,那再多一点也无所谓吧!OK,进入正题~ 下面是一个测试用例,test_one.py def test_passing():    assert (1, ...

  10. Linux 用 sftp scp命令 互传文件

    sftp它类似于 ftp, 但它进行加密传输,比FTP有更高的安全性. sftp 是SSH服务的子程序 常用命令 pwd 查看当前工作目录 ls 查看远程当前目录下的所以文件或者目录信息 lls 查看 ...