zoukankan      html  css  js  c++  java
  • Python 除了 time.sleep,你还有一个暂停代码的方法

    我们知道,在 Python 里面可以使用time.sleep来让代码暂停一段时间,例如:

    import time
    
    print('...部分代码...')
    time.sleep(5)
    print('...剩下的代码...')

    程序首先打印出...部分代码...,然后等待5秒钟,再打印出...剩下的代码...。

    现在大家想一想,有没有什么办法,在不使用time.sleep的情况下,让程序暂停5秒?

    你可能会说,用requests访问一个延迟5秒的网址、或者用递归版算法计算斐波那契数列第36位……这些奇技淫巧。

    不过今天我说的,是另外一个东西,threading模块里面的Event。

    我们来看看它的用法:

    import threading
    
    event = threading.Event()
    print('...部分代码...')
    event.wait(5)
    print('...剩下的代码...')

    这样一来,程序首先打印出...部分代码...,然后等待5秒钟,再打印出...剩下的代码...。

    功能看起来跟time.sleep没什么区别,那为什么我要特别提到它呢?因为在多线程里面,它比time.sleep更有用。我们来看一个例子:

    import threading
    
    class Checker(threading.Thread):
        def __init__(self, event):
            super().__init__()
            self.event = event
    
        def run(self):
            while not self.event.is_set():
                print('检查 redis 是否有数据')
                time.sleep(60)
    
    trigger_async_task()
    event = threading.Event()
    checker = Checker(event)
    checker.start()
    if user_cancel_task():
        event.set()

    我来解释一下这段代码的意思。在主线程里面,我调用trigger_async_task()触发了一个异步任务。这个任务多久完成我并不清楚。但是这个任务完成以后,它会往 Redis 里面发送一条消息,只要 Redis 有这个消息了,我就知道它完成了。所以我要创建一个 checker 子线程,每60秒去 Redis里面检查任务是否完成。如果没有完成,就暂停60秒,然后再检查。

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

    但是我们知道,线程是不能从外面主动杀死的,只能让它自己退出。所以当我执行event.set()后,子线程里面self.event.is_set()就会返回 False,于是这个循环就不会继续执行了。

    可是,如果某一轮循环刚刚开始,我在主线程里面调用了event.set()。此时,子线程还在time.sleep中,那么子线程需要等待60秒才会退出。

    但如果我修改一下代码,使用self.event.wait(60):

    import threading
    
    class Checker(threading.Thread):
        def __init__(self, event):
            super().__init__()
            self.event = event
    
        def run(self):
            while not self.event.is_set():
                print('检查 redis 是否有数据')
                self.event.wait(60)
    
    trigger_task()
    event = threading.Event()
    checker = Checker(event)
    checker.start()
    if user_cancel_task():
        event.set()

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

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

    注意:如果你是打算找python高薪工作的话。我建议你多写点真实的企业项目积累经验。不然工作都找不到,当然很多人没进过企业,怎么会存在项目经验呢? 所以你得多找找企业项目实战多练习下撒。如果你很懒不想找,也可以进我的Python交流圈:1156465813。群文件里面有我之前在做开发写过的一些真实企业项目案例。你可以拿去学习,不懂都可以在裙里找我,有空会耐心给你解答下。

    以下内容无用,为本篇博客被搜索引擎抓取使用
    (* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)
    python 是干什么的 零基础学 python 要多久 python 为什么叫爬虫
    python 爬虫菜鸟教程 python 爬虫万能代码 python 爬虫怎么挣钱
    python 基础教程 网络爬虫 python python 爬虫经典例子
    python 爬虫
    (* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)
    以上内容无用,为本篇博客被搜索引擎抓取使用

  • 相关阅读:
    为什么需要字节对齐?
    从sprintf函数谈符号扩展问题
    sprintf介绍
    char的本质
    使用sprintf连接字符串
    sscanf用法简介
    IE6,IE7,FF | CSS + DIV 兼容问题综合解决方案CSS HACK
    Div+css优点
    MS SQL数据库备份和恢复存储过程(加强版本)
    如何实现HTML页面无刷新更换CSS样式
  • 原文地址:https://www.cnblogs.com/shuchongzeishuai/p/13925439.html
Copyright © 2011-2022 走看看