当前位置: 首页 > article >正文

使用Redis构建任务队列

文章目录

  • 第1关:先进先出任务队列
  • 第2关:优先级任务队列
  • 第3关:定时任务队列


第1关:先进先出任务队列

编程要求
在Begin-End区域编写 add_task(task_name) 函数,实现将任务加入队列的功能,具体参数与要求如下:

方法参数 task_name 是要加入的任务名称;
推入任务的实现:将新的任务从列表 task:list 的尾部插入。
编写 pop_task() 函数,实现获取一个任务的功能,具体参数与要求如下:

获取任务的实现:从列表 task:list 的头部阻塞式的弹出一个值,最长等待10秒,若超时仍未获取到,则重试该操作,直至弹出一个值;
任务返回的实现:获取任务成功后,返回该值中弹出的元素值。
测试说明
平台会对你编写的代码进行测试:

测试输入:my_task;
预期输出:

测试 add_task 方法…
推入任务:my_task
当前任务队列:[‘my_task’]
测试 pop_task 方法…
出队列任务:my_task
当前任务队列:[]
在多线程下测试队列工作…
出队列任务:new task

代码示例如下:

#!/usr/bin/env python
#-*- coding:utf-8 -*-
 
import redis
 
conn = redis.Redis()
 
# 将任务加入队列
def add_task(task_name):
    # 请在下面完成要求的功能
    #********* Begin *********#
    conn.rpush("task:list",task_name)
    #********* End *********#
 
# 获取一个任务
def pop_task():
    # 请在下面完成要求的功能
    #********* Begin *********#
    while True:
        task = conn.blpop("task:list",10)
        if not task:
            continue
        return task[1]
 
    #********* End *********#

在这里插入图片描述

第2关:优先级任务队列

编程要求
在Begin-End区域编写 add_task_list(list_name, priority) 函数,实现设置任务队列优先级的功能,具体参数与要求如下:

方法参数 list_name 是要加入的任务队列名字,priority 是要设置的优先权重,值越大则级别越高;
设置队列优先级的实现:为了能按照优先权重排列任务队列,将任务队列加入到有序集合 task:priority 中,分值为 priority。
编写 add_task(list_name, task_name) 函数,实现将任务加入队列的功能,具体参数与要求如下:

方法参数 list_name 是要加入的任务队列名字,task_name 是要加入的任务名称;
推入任务的实现:将新的任务从指定的列表尾部插入。
编写 pop_task()函数,实现获取一个任务的功能,具体参数与要求如下:

排序任务队列的实现:将有序集合 task:priority 中的所有成员按照分值递减的顺序排列;
获取任务的实现:按照上述队列的顺序,从第一个非空列表的头部阻塞式的弹出一个值,最长等待10秒,若超时仍未获取到,则重试该操作,直至弹出一个值;
任务返回的实现:获取任务成功后,返回该值中弹出的元素值。
测试说明
平台会对你编写的代码进行测试:

测试输入:h,e,l,o,d,u,c,r;
预期输出:

测试 add_task_list 方法…
加入三个任务队列:[‘task:list:high’, ‘task:list:mid’, ‘task:list:low’]
测试 add_task 方法…
推入任务:h 到 task:list:high
推入任务:e 到 task:list:mid
推入任务:l 到 task:list:low
推入任务:o 到 task:list:high
推入任务:d 到 task:list:mid
推入任务:u 到 task:list:low
推入任务:c 到 task:list:high
推入任务:r 到 task:list:mid
当前 task:list:high 任务队列:[‘h’, ‘o’, ‘c’]
当前 task:list:mid 任务队列:[‘e’, ‘d’, ‘r’]
当前 task:list:low 任务队列:[‘l’, ‘u’]
测试 pop_task 方法…
出队列顺序:[‘h’, ‘o’, ‘c’, ‘e’, ‘d’, ‘r’, ‘l’, ‘u’]
当前 task:list:high 任务队列:[]
当前 task:list:mid 任务队列:[]
当前 task:list:low 任务队列:[]
在多线程下测试队列工作…
出队列任务:new task

代码示例如下:

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import redis

conn = redis.Redis()

# 新建任务队列/改变任务队列优先级
def add_task_list(list_name, priority):
    # 请在下面完成要求的功能
    #********* Begin *********#
    conn.zadd("task:priority",list_name,priority)
    #********* End *********#

# 将任务加入队列
def add_task(list_name, task_name):
    # 请在下面完成要求的功能
    #********* Begin *********#
    conn.rpush(list_name,task_name)
    #********* End *********#

# 获取一个任务
def pop_task():
    # 请在下面完成要求的功能
    #********* Begin *********#
    while True:
        task = conn.blpop(conn.zrevrange("task:priority",0,-1),10)
        if not task:
            continue
        return task[1]
 
    #********* End *********


在这里插入图片描述

第3关:定时任务队列

编程要求
在Begin-End区域编写 execute_later(task_name, delay=0) 函数,实现添加定时任务的功能,具体参数与要求如下:

方法参数 task_name 是要加入的任务名称,delay 是任务的延迟时间;
添加定时任务的实现:若延迟时间大于0,则将任务加入到有序集合 task:delayed 中,分值为任务的执行时间,等于当前时间戳加上延迟时间;
添加普通任务的实现:若延迟时间小于等于0,则将其插入到列表task:list的尾部。
编写 pop_task() 函数,实现转移可执行任务的功能,具体参数与要求如下:

获取队列中第一个任务的实现:不断尝试获取有序集合task:delayed中按分值递增顺序的第一个元素;
判断该任务是否可执行的实现:若未取到任务或者任务的执行时间未到,则休眠 0.01 秒,然后继续尝试获取第一个任务;
任务转移的实现:从有序集合task:delayed中移除该任务,成功后,将该任务插入到列表task:list的尾部。
测试说明
平台会对你编写的代码进行测试:

测试输入:无;
预期输出:

测试 execute_later 方法…
添加任务,task-0 ,延迟:0
添加任务,task-1 ,延迟:0.5
添加任务,task-2 ,延迟:0
添加任务,task-3 ,延迟:1.5
普通任务队列长度:2
定时执行任务队列内容:[‘task-1’, ‘task-3’]
测试 pop_task 方法…
等待0.6秒后,普通任务队列长度为:3
普通任务队列内容为:[‘task-0’, ‘task-2’, ‘task-1’]
等待1.6秒后,普通任务队列长度为:4
普通任务队列内容为:[‘task-0’, ‘task-2’, ‘task-1’, ‘task-3’]

代码示例如下:

#!/usr/bin/env python
#-*- coding:utf-8 -*-
 
import time
import redis
 
conn = redis.Redis()
 
# 添加定时任务
def execute_later(task_name, delay=0):
    # 请在下面完成要求的功能
    #********* Begin *********#
    if delay > 0:
        conn.zadd("task:delayed",task_name,time.time()+delay)
    else:
        conn.rpush("task:list",task_name)
 
    #********* End *********#
 
# 转移可执行任务
def pop_task():
    # 请在下面完成要求的功能
    #********* Begin *********#
    while True:
        task = conn.zrange("task:delayed",0,0,withscores=True)
        if not task or task[0][1] > time.time():
            time.sleep(0.01)
            continue
 
        task = task[0][0]
        if conn.zrem("task:delayed",task):
            conn.rpush("task:list",task)    
 
    #********* End *********#

在这里插入图片描述



http://www.kler.cn/a/155634.html

相关文章:

  • WordPress 6.7 “Rollins”发布
  • Spring Boot 中的全局异常处理器
  • SpringCloud学习笔记
  • 【JVM】关于JVM的内部原理你到底了解多少(八股文面经知识点)
  • MySql结合element-plus pagination的分页查询
  • 【ChatGPT】 如何让ChatGPT分析数据并得出结论
  • Hdoop学习笔记(HDP)-Part.02 核心组件原理
  • 基于SSM的职业高中智慧作业试题系统设计
  • 3dMax拼图生成工具Puzzle2D使用教程
  • Java Throwable
  • Spring中@Transactional注解
  • QueryRunner报红处理
  • electron-vue运用及案例代码
  • 后端项目连接数据库-添加MyBatis依赖并检测是否成功
  • flutter开发实战-为ListView去除Android滑动波纹
  • 在cmd下查看mysql表的结构信息
  • 【Android踩过的坑】13.Android Studio 运行成功,但APP没有安装上的问题
  • electron打包 Error output: !include: could not find:
  • 挖漏洞之SQL注入
  • Python---格式化输出与%百分号----涉及转义符 \ 反斜杠的使用
  • FLASK博客系列5——模板之从天而降
  • electerm下载和安装
  • YOLOv7+姿态估计Pose+tensort部署加速
  • MDETR 论文报告
  • MySQL中的锁(简单)
  • thinkphp 判断当前页 导航条高亮等方法