繁体   English   中英

如何在 Python 中使用多处理定期调用函数?

[英]How to periodically call a function using multiprocessing in Python?

我想调用一个函数,使用多处理库定期检查总线上的值(需要非阻塞)。 有一种使用线程库的方法,但它不使用多个进程。

我已经看到使用线程库的这种功能的示例代码,但我想使用多处理库来实现同样的事情。 多处理的官方文档状态:

“注意多处理不包含 threading.active_count()、threading.enumerate()、threading.settrace()、threading.setprofile()、threading.Timer 的类似物”

但是,在我看到的线程库示例中,它们使用 threading.Timer。 多处理是否有类似的功能?

import time, threading
def foo():
    print(time.ctime())
    threading.Timer(10, foo).start()

foo()

#output:
#Thu Dec 22 14:46:08 2011
#Thu Dec 22 14:46:18 2011
#Thu Dec 22 14:46:28 2011
#Thu Dec 22 14:46:38 2011

在 Python 中执行周期性操作

上面的代码是与线程库一起使用的示例。 另外,我想知道这是否是不好的做法,因为线程永远不会终止(.join())。

基本上,多处理模块中没有计时器类。 应该,但是看起来当他们从pyprocessing迁移到multiprocessing时,它们没有包含该部分。 在这里进行解释https://stackoverflow.com/a/25297863/6598433

您可以按照https://stackoverflow.com/a/25297758/6598433中的 dano手动为多处理库设置一个工作计时器。

from multiprocessing import Process, Event

class Timer(Process):
    def __init__(self, interval, function, args=[], kwargs={}):
        super(Timer, self).__init__()
        self.interval = interval
        self.function = function
        self.args = args
        self.kwargs = kwargs
        self.finished = Event()

    def cancel(self):
        """Stop the timer if it hasn't finished yet"""
        self.finished.set()

    def run(self):
        self.finished.wait(self.interval)
        if not self.finished.is_set():
            self.function(*self.args, **self.kwargs)
        self.finished.set()

在此处查看完整的问题: 为什么Python的多处理模块中没有Timer类?

要扩展 Nosvan 的答案以拥有一个真正的周期性计时器(它会漂移几毫秒),您只需像这样扩展Timer类:

from typing import Callable


class PeriodicTimer(Timer):
    def __init__(self, interval: int, function: Callable):
        super(PeriodicTimer, self).__init__(interval, function)

    def run(self):
        while not self.finished_event.is_set():
            # function callback could set the stop event
            self.function(*self.args, **self.kwargs)
            self.finished_event.wait(self.timeout)

我可以建议修改Timer类,使其在构造函​​数中没有可变参数:

from multiprocessing import Process
from multiprocessing import Event
from typing import Callable


class Timer(Process):
    def __init__(self, timeout: int, function: Callable, args=None, kwargs=None):
        super(Timer, self).__init__()
        self.timeout = timeout
        self.function = function
        self.args = [] if args is None else args
        self.kwargs = {} if kwargs is None else kwargs
        self.finished_event = Event()

    def cancel(self):
        """Stop the timer if it hasn't finished yet"""
        self.finished_event.set()

    def run(self):
        self.finished_event.wait(self.timeout)
        if not self.finished_event.is_set():
            self.function(*self.args, **self.kwargs)
        self.finished_event.set()

以下是为什么要避免可变默认参数的详尽解释:

https://web.archive.org/web/20200221224620/http://effbot.org/zone/default-values.htm

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM