欧博在线:线程行列数据共享与生产者消费者模子

admin 4个月前 (07-04) 科技 49 0

线程行列数据共享与生产者消费者模子

queue模块简介

  queue模块提供了多种行列,那么它主要是用于多线程编程中的数据共享。

  我们都知道统一历程下的数据是能被多个线程共享的,那么为什么这些线程在统一历程下还去使用行列呢?

 

  由于行列是: 管道 + 锁

 

  以是使用行列来存放多个线程中用于共享的数据照样为了保证其数据的安全性。

  queue模块中的行列主要是用于内陆测试中使用,正式上线时还得要使用Redis,这个是后话,我们先来看关于queue模块的使用。

       官方中文文档 

 

方式大全

 

queue模块中的行列方式大全 
方式名称 功效形貌
Queue.qsize() 返回当前行列的巨细
Queue.empty() 判断当前行列是否为空
Queue.full() 判断当前行列是否已满
Queue.put(item, block=True, timeout=None) item放入行列中,block参数为若是要操作的行列现在已满是否壅闭,timeout为超时时间。
Queue.put_nowait(item) 相当于 put(item, False),若是操作的行列已满则不举行壅闭,而是抛出Full异常。
Queue.get(block=True, timeout=None) 将项目从行列中取出,block参数为若是要操作的行列现在为空是否壅闭,timeout为超时时间。
Queue.get_nowait() 相当于 get(False),若是要操作的行列为空则不举行壅闭,而是抛出Empty异常。
Queue.task_done() 当消费者线程被join()壅闭后,生产者线程挪用此方式会住手消费者线程的壅闭状态。详情请见下面弥补
Queue.join() 当消费者线程被join()壅闭后,需守候消费者线程挪用task_done()方式后方可住手壅闭。详情请见下面的弥补
注重:如遇到异常情况请查看官方文档,这个模块的方式对照特殊 

 

三种差别的行列

  queue模块中,提供了三种行列。如下:

 

  queue.Queue:先进先出行列

  queue.LifoQueue:先进后出行列

  queue.PriorityQueue:优先级行列

 

import queue

# ==== 先进先出行列 ====

q1 = queue.Queue(maxsize=5)  # 该行列最大可存放5个项目
q1.put(1)   # 入队操作
q1.put(2)
q1.put(3)

print(q1.get())  # 出队操作
print(q1.get())
print(q1.get())

# ==== 执行效果  ====

"""
1
2
3
"""


# ==== 先进后出行列 ====

q2 = queue.LifoQueue(maxsize=5)  # 该行列最大可存放5个项目
q2.put(1)   # 入队操作
q2.put(2)
q2.put(3)

print(q2.get())  # 出队操作
print(q2.get())
print(q2.get())

# ==== 执行效果  ====

"""
3
2
1
"""

# ==== 优先级行列 ====

q3 = queue.PriorityQueue(maxsize=5)
q2.put([10,"优先级为10"])   # 入队操作
q2.put([20,"优先级为20"])
q2.put([30,"优先级为30"])

print(q2.get())  # 出队操作,若是想取出详细元素,加个 索引[1] 即可
print(q2.get())
print(q2.get())

# ==== 执行效果  ====

"""
[30, '优先级为30']
[20, '优先级为20']
[10, '优先级为10']
"""
三种行列的简朴适用

 

生产者消费者模子

  生产者消费者模子是一种头脑,也许意思就是我们不让天生者与消费者之间举行直接接触,而是通过某种缓冲的方式让彼此之间的耦合度降低。生产者生产出了产物,消费者就可以举行购置,若是没有产物就等着。

  那么这个时刻我们就可以使用行列了,由于行列里有壅闭的机制,我画一幅图,来看一眼。

来,我们尝试用代码实现一下:

import threading
import queue
import time


def producer():
    """生产者"""
name = "食神周树人" count = 1 # 计数器 while count < 11: # 天天只做10个包子 produce = "包子" print("包子做好了,这是今天的第{0}个包子".format(count)) q.put(produce + str(count)) # 将产物放在管道中 count += 1 time.sleep(0.4) # 厨师0.4秒做一个包子 def consumer(): """消费者"""
name = threading.current_thread().getName() print("{0}正在等包子".format(name)) while 1: try: food = q.get(timeout=2) # 等拿包子,最多等2秒 time.sleep(0.2) # 消费者0.2秒吃一个包子 print("{0}把{1}吃了,真好吃!".format(name, food)) except queue.Empty: # 有的人等的不耐烦就不等了 print("{0}说:等了这么久还没有,不等了".format(name)) return if __name__ == '__main__': q = queue.Queue(maxsize=10) # 一次最多放10个产物 name = ["大耳朵", "二狗", "三蛋子"] # 消费者姓名列表 for i in range(3): t1 = threading.Thread(target=consumer, name=name[i]) t1.start() producer() # 生产者启动,现在只有一个生产者,也可以多个 # ==== 执行效果 ==== """ 大耳朵正在等包子 二狗正在等包子 三蛋子正在等包子包子做好了,这是今天的第1个包子 三蛋子把包子1吃了,真好吃! 包子做好了,这是今天的第2个包子 二狗把包子2吃了,真好吃! 包子做好了,这是今天的第3个包子 大耳朵把包子3吃了,真好吃! 包子做好了,这是今天的第4个包子 三蛋子把包子4吃了,真好吃! 包子做好了,这是今天的第5个包子 二狗把包子5吃了,真好吃! 包子做好了,这是今天的第6个包子 大耳朵把包子6吃了,真好吃! 包子做好了,这是今天的第7个包子 三蛋子把包子7吃了,真好吃! 包子做好了,这是今天的第8个包子 二狗把包子8吃了,真好吃! 包子做好了,这是今天的第9个包子 大耳朵把包子9吃了,真好吃! 包子做好了,这是今天的第10个包子 三蛋子把包子10吃了,真好吃! 二狗说:等了这么久还没有,不等了 大耳朵说:等了这么久还没有,不等了 三蛋子说:等了这么久还没有,不等了 """

 

弥补:join()与task_done()

import threading
import queue
import time

def task_1():
    print("正在装器械..")
    time.sleep(3)
    q.put("玫瑰花")  # 正在装器械
    q.task_done()  # 通知对方可以取了


def task_2():
    q.join() # 壅闭守候通知,接到通知说明行列里里有器械了。
    print("取到了",q.get())  # 取器械


if __name__ == '__main__':

    q = queue.Queue(maxsize=5)

    t1 = threading.Thread(target=task_1,name="小明")
    t2 = threading.Thread(target=task_2,name="小花")

    t1.start()
    t2.start()

# ==== 执行效果 ====

"""
正在装器械..
取到了 玫瑰花
"""

 

,

欧博开户网址

欢迎进入欧博开户网址(Allbet Gaming):www.aLLbetgame.us,欧博网址开放会员注册、代理开户、电脑客户端下载、苹果安卓下载等业务。

Allbet声明:该文看法仅代表作者自己,与本平台无关。转载请注明:欧博在线:线程行列数据共享与生产者消费者模子

网友评论

  • (*)

最新评论

站点信息

  • 文章总数:1447
  • 页面总数:0
  • 分类总数:8
  • 标签总数:2650
  • 评论总数:313
  • 浏览总数:31953