Search code examples
pythonpython-multiprocessing

How to periodically call a function using multiprocessing in Python?


I would like to call a function that checks a value on a bus periodically using the multiprocessing library (non-blocking desired). There is a way to do it using the threading library but it doesn't use multiple processes.

I've seen example code of this kind of functionality using the threading library but I'd like to achieve the same thing using the multiprocessing library. The official documentation for multiprocessing states:

"Note multiprocessing contains no analogues of threading.active_count(), threading.enumerate(), threading.settrace(), threading.setprofile(), threading.Timer"

however, in the examples I've seen for the threading library, they use threading.Timer. Is there a similar function for multiprocessing?

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

Executing periodic actions in Python

The code above is an example for used with the threading library. Also, I was wondering if that was bad practice because the threads are never terminated (.join()).


Solution

  • Basically, there is no timer class in the multiprocessing module. It should be, but seems like that when they migrated from pyprocessing to multiprocessing they didn't include that part. It's explained here https://stackoverflow.com/a/25297863/6598433.

    You can make a working timer for the multiprocessing library manually as dano posted in https://stackoverflow.com/a/25297758/6598433

    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()
    

    Check here the full question: Why no Timer class in Python's multiprocessing module?