python学习——python的队列

  • python的Queue模块中提供了同步、线程安全的队列
  • 包括FiFO(先入先出)、LIFO(后入先出)、优先级队列
  • 这些队列都实现了锁原语,能够在多线程中直接使用,可以使用队列来实现进程间的同步

队列的实现和方法

  • 需要导入模块:import queue 或者from queue import Queue
  • 需要创建对象:q = queue.Queue() 或者Q = Queue()(使用from导入之后才能用)
  • 创建队列的时候,需要向Queue中设置参数,表示队列的长度;不传参数,表示可以无限往队列中添加数据

方法

  • qsize(),返回当前队列中包含的消息数量
  • empty(),如果队列为空,返回True,或者False
  • full(),如果队列满了,返回True或者False
  • get(),获取队列,timeout参数可以设置等待时间
  • get_nowait(),相当于get方法
  • put(),写入队列,其中存在三个参数
    • item,表示塞入队列中的数值
    • block=True,表示是否等待,默认等待
    • timeout=None,表示等待时间,默认None
  • put_nowait(),相当于put方法
    • 只有item参数,即塞入队列中的数值
  • task_done(),在完成一项工作之后,使用这个方法向队列发出一个信号,表示该任务执行完毕
  • join(),实际上分意味着等到队列中所有任务执行完毕之后,再往下继续执行,否则就一直等待
    • 注意:join的的判断依据,不仅仅是指队列中没有数据,数据get出去之后,要使用task_done发送一个信号,表示任务执行完毕
    • task_done执行必须在join之前,且task_done执行的次数要大于等于任务个数,例如插入三次或者获取数据三次,就要写三条语句,否则会在join处阻塞,取法向下运行

先进先出的代码实现

import  queue

q = queue.Queue(3)  # 创建队列,10表示队列长度
for i in range(10,7,-1):
    q.put(i)
    # 如果队列满了,就会等待(默认)
    # 如果设置了不等待,就不会等待,队列已满,就报错
    # 和put_nowait一样
print("num:",q.qsize())
print("is null:",q.empty())
print("是否满队列:",q.full())
print("队列元素:",q.get()) # 先添加进去的先出来
print("队列元素:",q.get())
print("队列元素:",q.get())
# 获取完之后,也会等待(默认),参数和put一样
# get_nowait也只有item参数
# 队列无元素,也和get设置了不等待一样,报错
print("获取完,队列是否为空:",q.empty())
q.task_done() # 获取完数据之后,就要发一个信号
q.task_done()
q.task_done()
a = q.join() # 如果信号数小于执行语句,就会一直等待
print("join的执行结果:",a)

***********run_result***********
num: 3
is null: False
是否满队列: True
队列元素: 10
队列元素: 9
队列元素: 8
获取完,队列是否为空: True
join的执行结果: None

后进先出的代码实现

  • 后进先出,需要使用LifoQueue方法,代码如下
from  queue import LifoQueue

q = LifoQueue(3)  # 创建队列,10表示队列长度
for i in range(10,7,-1):
    q.put(i)
    # 如果队列满了,就会等待(默认)
    # 如果设置了不等待,就不会等待,队列已满,就报错
    # 和put_nowait一样
print("num:",q.qsize())
print("is null:",q.empty())
print("是否满队列:",q.full())
print("队列元素:",q.get()) # 后进先出
print("队列元素:",q.get())
print("队列元素:",q.get())
# 获取完之后,也会等待(默认),参数和put一样
# get_nowait也只有item参数
# 队列无元素,也和get设置了不等待一样,报错
print("获取完,队列是否为空:",q.empty())
q.task_done() # 获取完数据之后,就要发一个信号
q.task_done()
q.task_done()
a = q.join() # 如果信号数小于执行语句,就会一直等待
print("join的执行结果:",a)

优先级队列

  • 插入元素的时候要插入元组,(优先级,数据)
  • 获取数据的时候,按照优先级的大小,从小到大获取
from queue import PriorityQueue

q = PriorityQueue(3)  # 创建队列,10表示队列长度
data = {2:5,0:10,1:6}
for k,v in data.items():
    q.put((k,v))
    # 优先级队列设置元素:元组形式(优先级,数值)
print("num:",q.qsize())
print("is null:",q.empty())
print("是否满队列:",q.full())
print("队列元素:", q.get())  # 按照优先级的大小,由小到大获取
print("队列元素:", q.get())  # 获取的结果是个数组
print("队列元素:",q.get())
# 获取完之后,也会等待(默认),参数和put一样
# get_nowait也只有item参数
# 队列无元素,也和get设置了不等待一样,报错
print("获取完,队列是否为空:",q.empty())
q.task_done() # 获取完数据之后,就要发一个信号
q.task_done()
q.task_done()
a = q.join() # 如果信号数小于执行语句,就会一直等待
print("join的执行结果:",a)
***************run_result***************
num: 3
is null: False
是否满队列: True
队列元素: (0, 10)
队列元素: (1, 6)
队列元素: (2, 5)
获取完,队列是否为空: True
join的执行结果: None

例题

  • 1,使用一个队列来存储商品
  • 2,创建一个专门生产圣品的线程类,当商品数量小于50时,开始生产商品
  • 每次生产200个商品,每生产一轮,暂停1s
  • 3,创建一个专门消费商品的线程类,当商品数量大于10时,开始消费
  • 循环消费,每次消费3个,当商品个数小于10时,暂停2s
  • 4,创建一个线程生产商品,5个线程消费商品
import threading
from queue import Queue
import time

q = Queue()

class Product(threading.Thread):
    """ 生产者线程类 """

    def  run(self):
        count = 0
        while True:
            if q.qsize() <50:
                for i in range(200):
                    count+=1
                    goods = "第{}个商品".format(count)
                    q.put(goods)
                    print("生产:",goods)
            time.sleep(2)


class Consumer(threading.Thread):
    """ 消费者线程类 """

    def run(self):
        while True:
            if q.qsize() >10:
                for i in range(3):
                    a = q.get()
                    print(" 获得商品:", a)
            else:
                time.sleep(2)

p = Product()
p.start()
for i in range(5):
    c = Consumer()
    c.start()
  • 不用重写的方式来做:
import threading
from queue import Queue
import time

q = Queue()

class ProAndCons:

    def product_goods(self):
        while True:
            print(q)
            if q.qsize()<50:
                for i in range(200):
                    goods = "第{}个元素".format(i)
                    q.put(goods)
                    print("goods:",goods)
            time.sleep(2)


    def cons_goods(self):
        while True:
            print(q)
            print(q.qsize())
            if q.qsize() >=10:
                for i in range(3):
                    g = q.get()
                    print("商品:",g)
            else:
                time.sleep(2)

t = threading.Thread(target=ProAndCons().product_goods)
t.start()
time.sleep(10)
for i in range(5):
    print("11")
    c = threading.Thread(target=ProAndCons().cons_goods)
    c.start()
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是 Python 实现 A* 算法的代码: ```python from queue import PriorityQueue class State: def __init__(self, value, parent, start=0, goal=0): self.children = [] self.parent = parent self.value = value self.distance = 0 if parent: self.start = parent.start self.goal = parent.goal self.path = parent.path[:] self.path.append(value) else: self.start = start self.goal = goal self.path = [value] def get_distance(self): pass def create_children(self): pass class State_String(State): def __init__(self, value, parent, start=0, goal=0): super().__init__(value, parent, start, goal) self.distance = self.get_distance() def get_distance(self): if self.value == self.goal: return 0 distance = 0 for i in range(len(self.goal)): letter = self.goal[i] distance += abs(i - self.value.index(letter)) return distance def create_children(self): if not self.children: for i in range(len(self.goal) - 1): val = self.value val = val[:i] + val[i+1] + val[i] + val[i+2:] child = State_String(val, self) self.children.append(child) class AStar_Solver: def __init__(self, start, goal): self.path = [] self.visited_queue = [] self.priority_queue = PriorityQueue() self.start = start self.goal = goal def solve(self): start_state = State_String(self.start, None, self.start, self.goal) count = 0 self.priority_queue.put((0, count, start_state)) while not self.path and self.priority_queue.qsize(): closest_child = self.priority_queue.get()[2] closest_child.create_children() self.visited_queue.append(closest_child.value) for child in closest_child.children: if child.value not in self.visited_queue: count += 1 if not child.distance: self.path = child.path break self.priority_queue.put((child.distance, count, child)) if not self.path: print("Goal of " + self.goal + " is not possible!") return self.path start = "dabcfehg" goal = "abcdefgh" a = AStar_Solver(start, goal) a.solve() print(a.path) ``` 在上述代码,`State` 类表示状态,包含当前状态值、父状态、起始状态、目标状态、路径和距离等属性。`State_String` 类是 `State` 类的子类,用于处理字符串类型的状态。`get_distance` 函数用于计算当前状态与目标状态之间的距离,`create_children` 函数用于创建当前状态的子状态。 `AStar_Solver` 类是 A* 算法的主要实现部分。在 `__init__` 函数,我们初始化路径和队列等属性。在 `solve` 函数,我们首先将起始状态加入优先队列,并不断从队列取出距离最短的状态,生成其子状态,并将未访问过的子状态加入优先队列。在每次加入子状态到队列时,我们使用 `count` 属性来确保优先队列的元素是按照加入顺序排序的。当找到目标状态时,我们提取路径并返回。 最后,我们通过调用 `AStar_Solver` 类来解决字符串类型的问题。在此例,我们使用字符串 "dabcfehg" 作为起始状态,使用字符串 "abcdefgh" 作为目标状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值