您的位置:首页 > 编程语言 > Python开发

[ Python - 12 ] 线程的信号量、标志位及队列

2017-08-01 14:32 483 查看

线程的信号量

线程的信号量是同时允许一定数量的线程更改数据,主要作用在于限制线程的并发。

#!_*_coding:utf-8_*_
# Author: hkey
import threading, time
# 线程的信号量
sem = threading.BoundedSemaphore(5)     # 实例化信号量并限制并发为5个线程
def run():
sem.acquire()    # 开始
print('running...', threading.get_ident())
time.sleep(1)
sem.release()    # 结束
if __name__ == '__main__':
for i in range(20):
t = threading.Thread(target=run)
t.start()


线程的标志位Events

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

事件处理的机制:全局定义一个Flag. 使用threading.Event 实现线程间通信 event = threading.Event() 初始值为False

如果'Flag'值为False,那么当程序执行event.wait方法时就会阻塞

如果'Flag'值为True,那么event.wait方法便不在阻塞

clear: 将'Flag'设置为False

set:将'Flag'设置为True

一旦该线程通过wait()方法进入等待状态,直到另一个线程调用Event的set()方法将内置标志设置为True时,该Event会通知所有等待状态的线程恢复运行。

#!_*_coding:utf-8_*_
# Author: hkey
import threading, time
# 线程的标志位
# 红绿灯, 灯控制车辆
event = threading.Event()

def light():
n = 0
while True:
if n <= 5:
event.set()     # 设置为set, wait就不阻塞 绿灯状态
print('\33[42;1m green light \33[0m')
elif 5 < n < 10:
event.clear()     # 将'Flag'设置为False 红灯状态
print('\33[41;1m red light \33[0m')
else:
n = 0
time.sleep(1)
n += 1

def car():
while True:
if event.is_set():
print('cars running...')
else:
print('cars stopped...')
event.wait()     # 当使用clear方法将Flag为False,使用wait方法阻塞;当使用set方法将Flag设置为True,则恢复运行
time.sleep(1)

t1 = threading.Thread(target=light)
t2 = threading.Thread(target=car)
t1.start()
t2.start()


线程的队列

线程的队列共有三种:

class queue.Queue(maxsize=0) #先入先出
class queue.LifoQueue(maxsize=0) # 先入后出
class queue.PriorityQueue(maxsize=0) #存储数据时可设置优先级的队列


这里主要使用先入先出模式

生产者消费者模型

生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

#!_*_coding:utf-8_*_
# Author: hkey
import threading, queue, time
q = queue.Queue()
def product():
for i in range(10):
q.put('包子-%s' %i)   # 循环put 10个包子
print('等待取包子')
q.join()    # 阻塞等待队列被清空
print('所有包子都被取走了。')

def consumer():
while not q.empty():    # empty()方法判断队列是否为空,空为True
print('吃掉%s' %q.get())
q.task_done()       # 告知这个任务执行完了
time.sleep(1)

t1 = threading.Thread(target=product)
t2 = threading.Thread(target=consumer)
t1.start()
t2.start()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐