目录

一.  基础知识

1.入队

2.出队

3.阻塞等待

返回值

二.  入队出队设计

1.思路

2.代码实现

三.  应用介绍

1.队列

2.进程队列queue


 

 

一.  基础知识

1.入队

  • rpush:把值插到列表的右边(尾部)r = right
  • lpush:把值插到列表的左边(头部) l = left

2.出队

  • rpop:移除列表的最后一个元素,返回值为移除的元素。(右边,尾部)
  • lpop:移出并获取列表的第一个元素(左边,头部)

3.阻塞等待

如果在规定时间timeout内,没有数据,则会挂起等待。
timeout=10,意思是在生命周期内有值就直接返回,不用等待10s结束

(1).  brpop

  • 命令移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
  • 假如在指定时间内没有任何元素被弹出,则返回一个 nil 和等待时长。 反之,返回一个含有两个元素的列表,第一个元素是被弹出元素所属的 key ,第二个元素是被弹出元素的值。

(2).  blpop

  • 命令移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
  • 如果列表为空,返回一个 nil 。 否则,返回一个含有两个元素的列表,第一个元素是被弹出元素所属的 key ,第二个元素是被弹出元素的值
  • 第一个参数是key值,第二个参数timeOut是等待的时间,如果指定的列表存在数据则返回第一个元素,否则等待timeOut秒后返回nil

(3).  brpoplpush

  • Redis Brpoplpush 命令从列表中取出最后一个元素,并插入到另外一个列表的头部; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
  • 返回值

    假如在指定时间内没有任何元素被弹出,则返回一个 nil 和等待时长。 反之,返回一个含有两个元素的列表,第一个元素是被弹出元素的值,第二个元素是等待时长。

  • 幂等性的ack操作,也就是确认操作(幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同

二.  入队出队设计

1.思路

  • 如果从左边入队(lpush),那么出队就是往右边(rpop);
  • 如果从右边入队(rpush),那么出队就是往左边( lpop);

2.代码实现

import asyncio


class AuditQueue:

    def __init__(self):

        self.r = redis.Redis(decode_responses=True,password=123)
        self.key = "auditlist"


    # 入队
    async def push(self,item):
        self.r.lpush(self.key,item)

    # 出队
    async def out(self):

        item = self.r.rpop(self.key)
        return item

    # 等待出队  在生命周期内有值就直接返回,不用等待10s
    async def bout(self):
        # 幂等性的ack操作,确认操作
        item = self.r.brpoplpush(self.key,"backqueue",timeout=10)
        return item


async def main():
    aq = AuditQueue()

    await aq.push(1)

asyncio.run(main())

三.  应用介绍

1.队列

队列(Queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。允许插入的端是队尾,允许删除的端是队头。

所以说队列是一个先进先出的线性表,相应的也有顺序存储和链式存储两种方式

2.进程队列queue

不同于线程queue,进程queue的生成是用multiprocessing模块生成的。

在生成子进程的时候,会将代码拷贝到子进程中执行一遍,及子进程拥有和主进程内容一样的不同的名称空间。

multiprocess.Queue 是跨进程通信队列

常用方法:

q.put方法用以插入数据到队列中,put方法还有两个可选参数:blocked和timeout。如果blocked为True(默认值),并且timeout为正值,该方法会阻塞timeout指定的时间,直到该队列有剩余的空间。如果超时,会抛出Queue.Full异常。如果blocked为False,但该Queue已满,会立即抛出Queue.Full异常。
q.get方法可以从队列读取并且删除一个元素。同样,get方法有两个可选参数:blocked和timeout。如果blocked为True(默认值),并且timeout为正值,那么在等待时间内没有取到任何元素,会抛出Queue.Empty异常。如果blocked为False,有两种情况存在,如果Queue有一个值可用,则立即返回该值,否则,如果队列为空,则立即抛出Queue.Empty异常.
q.get_nowait():同q.get(False)
q.put_nowait():同q.put(False)
q.empty():调用此方法时q为空则返回True,该结果不可靠,比如在返回True的过程中,如果队列中又加入了项目。
q.full():调用此方法时q已满则返回True,该结果不可靠,比如在返回True的过程中,如果队列中的项目被取走。
q.qsize():返回队列中目前项目的正确数量,结果也不可靠,理由同q.empty()和q.full()一样

问题:

队列

线程间使用队列进行通信,因为队列所有方法都是线程安全的,所以不会出现线程竞争资源的情况

Queue.Queue 是进程内非阻塞队列

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐