返回顶部
首页 > 资讯 > 精选 >上下文管理器和守护线程
  • 494
分享到

上下文管理器和守护线程

2024-02-06 10:02:04 494人浏览 八月长安
摘要

问题内容 我正在从上下文管理器启动一个守护线程,该线程应该每秒发送一次心跳,但由于它在线程中运行,因此如果发生异常,它不会终止上下文管理器。当心跳停止时,如何在上下文管理器中引发异常?

问题内容

我正在从上下文管理器启动一个守护线程,该线程应该每秒发送一次心跳,但由于它在线程中运行,因此如果发生异常,它不会终止上下文管理器。当心跳停止时,如何在上下文管理器中引发异常?

from contextlib import contextmanager
from threading import Thread, Event
from time import sleep


@contextmanager
def plc():
    stop_event = Event()

    try:
        # Send heartbeat every second
        hb_t = Thread(target=heartbeat_task,
                      args=(stop_event,),
                      daemon=True)
        hb_t.start()

        yield
    except Exception:
        raise
    finally:
        stop_event.set()
        hb_t.join()
        print("Heartbeat stopped")


def heartbeat_task(stop_event):

    value = False
    
    while not stop_event.is_set():

        value = not value

        print("Heartbeat: " + str(value))

        sleep(1)


def main():

    with plc():

        while True:

            print("Program running")

            sleep(5)

if __name__ == '__main__':
    main()

我很难找到这方面的例子。

感谢您的帮助!


正确答案


更新

我已经修改了代码,使其与您发布的代码更加一致。但是:

您提供的代码不一致:heartbeat_task 传递了一个事件,如果设置该事件将导致函数返回。但只有当使用 with plc(): 创建的函数 main 中的上下文管理器退出时才会设置它,而这是永远不会的。如果您希望 heartbeat_task 抛出的任何异常将强制上下文管理器退出,然后在函数 plc 中捕获,那么调用 stop_event.set() 的意义何在?如果根据定义,我们仅在 heartbeat_task 不再存在时才到达这里由于异常而运行?

因此,要么您希望 heartbeat_task 无限期地运行,直到引发异常(在这种情况下,没有“停止”事件的意义),要么您希望能够在存在某些条件时停止 heartbeat_task,但没有这样做的代码。出于演示目的,我假设 main 将有权访问 stop_event 事件,并在某些情况下对其进行设置。否则,它会一直运行,直到检测到 heartbeat_task 不再运行,可能是因为它引发了异常(它正在执行无限循环,所以如果尚未设置停止事件,它怎么可能终止?)。剩下的就是为什么您需要使用上下文管理器。稍后我将提出一个替代方案。

如果您使用多线程池(我们只需要池中的一个线程),那么主线程捕获提交到池的任务抛出的异常就变得很简单:当 multiprocessing.pool.threadpool.apply_async 被调用时返回 multiprocessing.pool.asyncresult 实例,表示未来的完成。当在此实例上调用 get 方法时,您可以从辅助函数 (heartbeat_task) 获取返回值,或者重新引发辅助函数引发的任何异常。但是我们也可以使用 wait 方法来等待提交任务的完成或经过的时间。然后我们可以使用 ready 方法测试等待 5 秒后提交的任务是否真正完成(由于异常或返回)。如果任务仍在运行,那么我们可以告诉它停止。在此演示中,我强制任务在大约 7 秒后引发异常:

from contextlib import contextmanager
from threading import event
from multiprocessing.pool import threadpool
from time import sleep


@contextmanager
def plc():
    stop_event = event()
    pool = threadpool(1)

    # send heartbeat every second
    async_result = pool.apply_async(heartbeat_task, args=(stop_event,))
    yield stop_event, async_result
    # we only return here if the task is no longer running
    try:
        # see if task threw an exception and if so, catch it:
        async_result.get()
    except exception as e:
        print("Got exception:", e)
    finally:
        pool.close()
        pool.join()
        print("heartbeat stopped")


def heartbeat_task(stop_event):
    # for demo purposes, we will force an exception to occur
    # after approximately 7 seconds:
    value = false

    n = 0
    while not stop_event.is_set():
        value = not value
        print("heartbeat: " + str(value))
        sleep(1)
        n += 1
        if n == 7:
            raise exception('oops!')


def main():
    with plc() as tpl:
        stop_event, async_result = tpl
        # this function could forcibly cause the heartbeat_task
        # to complete by calling stop_event.set()

        # loop while the task is still running
        while not async_result.ready():
            """
            if some_condition:
                stop_event.set()
                break
            """
            print("program running")
            # sleep for 5 seconds or until heartbeat_task terminates:
            async_result.wait(5)

if __name__ == '__main__':
    main()

打印:

program running
heartbeat: true
heartbeat: false
heartbeat: true
heartbeat: false
heartbeat: true
program running
heartbeat: false
heartbeat: true
got exception: oops!
heartbeat stopped

使用上下文管理器的替代方法

from threading import Event
from multiprocessing.pool import ThreadPool
from time import sleep


def heartbeat_task(stop_event):
    value = False

    n = 0
    while not stop_event.is_set():
        value = not value
        print("Heartbeat: " + str(value))
        sleep(1)
        n += 1
        if n == 7:
            raise Exception('Oops!')

def main():
    stop_event = Event()
    pool = ThreadPool(1)
    async_result = pool.apply_async(heartbeat_task, args=(stop_event,))

    # Run as long as heartbeat_task is running:
    while not async_result.ready():
        """
        if some_condition:
            stop_event.set()
            break
        """
        print("Program running")
        # Sleep for 5 seconds or until heartbeat_task terminates:
        async_result.wait(5)

    # Any exception thrown in heartbeat_task will be rethrown and caught here:
    try:
        async_result.get()
    except Exception as e:
        print("Got exception:", e)
    finally:
        pool.close()
        pool.join()

if __name__ == '__main__':
    main()

以上就是上下文管理器和守护线程的详细内容,更多请关注编程网其它相关文章!

--结束END--

本文标题: 上下文管理器和守护线程

本文链接: https://lsjlt.com/news/561464.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 上下文管理器和守护线程
    问题内容 我正在从上下文管理器启动一个守护线程,该线程应该每秒发送一次心跳,但由于它在线程中运行,因此如果发生异常,它不会终止上下文管理器。当心跳停止时,如何在上下文管理器中引发异常?...
    99+
    2024-02-06
  • Java守护线程和用户线程的区别
    目录守护线程定义创建守护线程将线程池设置为守护线程守护线程 VS 用户线程用户线程守护线程守护线程注意事项总结前言: 在 Java 语言中,线程分为两类:用户线程和守护线程,默认情况...
    99+
    2024-04-02
  • openSUSE中如何管理服务和守护进程
    在openSUSE中,可以使用systemd来管理服务和守护进程。以下是一些常用的命令和操作: 启动一个服务: sudo sys...
    99+
    2024-04-02
  • 怎么理解java高并发的用户线程和守护线程
    这篇文章主要讲解了“怎么理解java高并发的用户线程和守护线程”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解java高并发的用户线程和守护线程”吧!守护线程是一种特殊的线程,在后台默...
    99+
    2023-06-25
  • Java中用户线程和守护线程有什么区别
    这篇文章给大家分享的是有关Java中用户线程和守护线程有什么区别的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。在 Java  语言中线程分为两类:用户线程和守护线程,而二者之间的区别却鲜有人知,所以本文...
    99+
    2023-06-15
  • java高并发的用户线程和守护线程详解
    目录程序只有守护线程时,系统会自动退出设置守护线程,需要在start()方法之前进行线程daemon的默认值总结守护线程是一种特殊的线程,在后台默默地完成一些系统性的服务,比如垃圾回...
    99+
    2024-04-02
  • Java中守护线程和用户线程的区别有哪些
    这篇文章主要介绍Java中守护线程和用户线程的区别有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!常用的java框架有哪些1.SpringMVC,Spring Web MVC是一种基于Java的实现了Web MV...
    99+
    2023-06-14
  • 数据库的守护者:使用 DDL 维护和管理数据
    DDL是SQL(结构化查询语言)的重要组成部分,用于定义和操作数据库结构。它提供了一系列命令,使 DBA 能够创建、修改和删除数据库对象,包括表、索引、视图和存储过程。 创建数据库对象 DDL 最基本的用途是创建数据库对象。以下是一个示...
    99+
    2024-02-19
    数据库定义语言 DDL 数据管理 数据库维护
  • django-10-中间件和上下文管理器
    <<<中间件的引入>>> 用户<->中间件<->url->视图  在app目录里面 middleware.py  (1)中间件就是一个可调用的对象,接受一个request并...
    99+
    2023-01-31
    上下文 管理器 中间件
  • node.js应用后台守护进程管理器Forever安装和使用实例
    我们不可能直接通过node命令来管理远程站点,这样无法保证网站的可持续运行。我们用Forever来解决这个问题,它可以将NodeJS应用以后台守护进程的方式运行,我们还可以将NodeJS应用设成随系统启动而...
    99+
    2022-06-04
    管理器 后台 实例
  • Python编程ContextManager上下文管理器讲解
    目录什么是上下文管理器官方解释简单一句话__enter__(self)__exit__(self, exc_type, exc_value, exc_traceback)有哪些常见上...
    99+
    2024-04-02
  • Python上下文管理器Content Manager
    在 Python 中,我们会经常听到上下文管理器(Context Manager),那我们探讨下这是什么,又有什么功能。 在 Python 中的上下文管理器中,使用 with 打开文件是使用最多的,其中离开 wit...
    99+
    2022-06-02
    Python上下文管理器 Python Content Manager
  • 什么是上下文管理器
    一、上下文管理器 上下文管理器(Context Manager)是Python中的一种编程模式,用于管理资源的获取和释放。它通过定义一个特定的上下文环境,确保在进入和离开这个环境时,相关资源会被正确地获取和释放。 二、实现方式 在Pytho...
    99+
    2023-10-29
    上下文 管理器
  • Python上下文管理器详细使用教程
    目录上下文管理器和with块contextlib模块@contextmanager 装饰器@contextmanager 原理和注意事项with语句会设置一个临时的上下文,交给上下文...
    99+
    2023-02-08
    Python上下文管理器 Python上下文
  • python上下文管理器是什么
    本篇文章给大家分享的是有关python上下文管理器是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。python的五大特点是什么python的五大特点:1.简单易学,开发程序...
    99+
    2023-06-14
  • Python深入02 上下文管理器
    上下文管理器(context manager)是Python2.5开始支持的一种语法,用于规定某个对象的使用范围。一旦进入或者离开该使用范围,会有特殊操作被调用 (比如为对象分配或者释放内存)。它的语法形式是with...as...关闭文件...
    99+
    2023-06-02
  • 详解Python中的with语句和上下文管理器
    目录一、with语句的使用二、上下文管理器三、小结如果你有阅读源码的习惯,可能会看到一些优秀的代码经常出现带有 with 关键字的语句,它通常用在什么场景呢?对于系统资源如文件、数据...
    99+
    2024-04-02
  • Python上下文管理器怎么使用
    这篇文章主要介绍了Python上下文管理器怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Python上下文管理器怎么使用文章都会有所收获,下面我们一起来看看吧。什么是上...
    99+
    2024-04-02
  • Python上下文管理器深入讲解
    目录引子概念上下文管理协议(Context Management Protocol)上下文管理器(Context Manager)引子 上下文管理器是一种简化代码的有力方式,其内部也...
    99+
    2022-12-21
    Python上下文管理器 Python上下文
  • 深人了解Python上下文管理器
    目录with语句上下文管理器创建基于类的上下文管理器@contextmanager 装饰器总结下面先来介绍一下with关键字在文件读写中的应用,简单了解上下文管理器的功能。 with...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作