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

python-中断time.sleep一种更优雅的办法:event.wait

场景描述:

实现一个功能,启动一个线程,只要线程不中断,就一直while true,间断10s累加某个数;

当线程线程信号时,while停止,线程退出。

1、方法一 time.sleep

import time
from threading import Thread


class AddTask(Thread):

    def __init__(self):
        super().__init__()
        self.sum_num = 0
        self._button = True

    def run(self):
        print('Begin to add ...')
        while self._button:
            print('Sleep start...')
            time.sleep(10)
            print('Sleep end...')
            self.sum_num += 10
        print(f"Finish add, sum:{self.sum_num}...")

    def stop(self):
        print('Stop task...')
        self._button = False


def do_main_task():
    print('Do main task...')
    time.sleep(15)
    print('Finish main task...')
    return True


if __name__ == '__main__':
    add_task = AddTask()
    add_task.start()
    main_task_end = do_main_task()
    if main_task_end:
        add_task.stop()
        time.sleep(1)
        print(f"sum: {add_task.sum_num}")

执行结果:

Begin to add ...Do main task...
Sleep start...
Sleep end...
Sleep start...
Finish main task...
Stop task...
sum: 10
Sleep end...
Finish add,sum: 20...

解释一下这段代码的意思。在主线程里面,我调用do_main_task()触发了一个任务。这个任务执行会久一些(这里设定15s)。但是这个任务完成以后,会有个返回值,告诉我完成了。另外创建一个 add_task 子线程,每10秒累加10。

但某些情况下,我不需要等待了,例如用户主动取消了任务。这个时候,我就想提前结束这个 add_task 子线程。

通过执行结果可以看出,当执行一次+10,等待10s后,又过了5秒,主线程do_main_task结束了,这时add_task线程还在累加的sleep(10)中没有退出。主线程执行结果已经是sum=10,再过5秒后add_task线程才结束。

但是,线程是不能从外面主动杀死的,只能让它自己退出。

2、方法二 event.wait

应用threading模块里面的Event,

用法和sleep差不多:

import threading

event = threading.Event()
event.wait(5)

上述例子可以这样实现:

import time
from threading import Thread
from threading import Event


class AddTask(Thread):

    def __init__(self):
        super().__init__()
        self.sum_num = 0
        self.event = Event()

    def run(self):
        print('Begin to add ...')
        while not self.event.is_set():
            print('Sleep start...')
            self.event.wait(10)
            print('Sleep end...')
            self.sum_num += 10
        print(f"Finish add, sum:{self.sum_num}...")

    def stop(self):
        print('Stop task...')
        self.event.set()


def do_main_task():
    print('Do main task...')
    time.sleep(15)
    print('Finish main task...')
    return True


if __name__ == '__main__':
    add_task = AddTask()
    add_task.start()
    main_task_end = do_main_task()
    if main_task_end:
        add_task.stop()
        time.sleep(1)
        print(f"sum: {add_task.sum_num}")

执行结果:

Do main task...
Begin to add ...
Sleep start...
Sleep end...
Sleep start...
Finish main task...
Stop task...
Sleep end...
Finish add, sum:20...

sum: 20

当执行event.set()后,子线程里面self.event.is_set()就会返回 False,于是这个循环就不会继续执行了。

即使self.event.wait(10)刚刚开始阻塞,只要我在主线程中执行了event.set(),子线程里面的阻塞立刻就会结束。于是子线程立刻就会结束。不需要再白白等待10秒。

并且,event.wait()这个函数在底层是使用 C 语言实现的,不受 GIL 锁的干扰。

 

相关文章:

  • 【毕业设计】大数据公交数据分析与可视化 - 大数据 python falsk
  • Hadoop与Spark中的Shuffle过程梳理
  • CH9101芯片应用—硬件设计指南
  • [NCTF2019]True XML cookbook
  • 湖仓一体电商项目(十二):编写写入DM层业务代码
  • 遥感生态指数(RSEI)——四个指数的计算
  • 9--RNN
  • JDBC的使用
  • 《Mycat分布式数据库架构》之数据切分实战
  • SpringBoot使用spring.config.import多种方式导入配置文件
  • 【框架】Spring Framework :SpringBoot
  • Linux内核之waitqueue机制
  • 前端面试:webpack整理
  • 7. PyEcharts
  • springboot启动报错:Failed to start bean ‘documentationPluginsBootstrapper‘
  • (ckeditor+ckfinder用法)Jquery,js获取ckeditor值
  • 【知识碎片】第三方登录弹窗效果
  • Android交互
  • AWS实战 - 利用IAM对S3做访问控制
  • Python学习之路16-使用API
  • SpiderData 2019年2月13日 DApp数据排行榜
  • Sublime text 3 3103 注册码
  • 微服务入门【系列视频课程】
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 我有几个粽子,和一个故事
  • 线上 python http server profile 实践
  • 中文输入法与React文本输入框的问题与解决方案
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • ​第20课 在Android Native开发中加入新的C++类
  • #Spring-boot高级
  • #在线报价接单​再坚持一下 明天是真的周六.出现货 实单来谈
  • (0)Nginx 功能特性
  • (04)odoo视图操作
  • (libusb) usb口自动刷新
  • (定时器/计数器)中断系统(详解与使用)
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (蓝桥杯每日一题)love
  • (数位dp) 算法竞赛入门到进阶 书本题集
  • (一)ClickHouse 中的 `MaterializedMySQL` 数据库引擎的使用方法、设置、特性和限制。
  • (转)linux下的时间函数使用
  • .NET Core 版本不支持的问题
  • .NET Core 中的路径问题
  • .NET MVC 验证码
  • .Net6支持的操作系统版本(.net8已来,你还在用.netframework4.5吗)
  • .NET命名规范和开发约定
  • .NET下的多线程编程—1-线程机制概述
  • .NET中的十进制浮点类型,徐汇区网站设计
  • .secret勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复
  • @column注解_MyBatis注解开发 -MyBatis(15)
  • @javax.ws.rs Webservice注解
  • @RequestMapping用法详解
  • [Big Data - Kafka] kafka学习笔记:知识点整理
  • [BT]BUUCTF刷题第4天(3.22)
  • [BZOJ1178][Apio2009]CONVENTION会议中心
  • [bzoj2957]楼房重建