1

I have code to update a dictionary real-time. Now, I want to create a timer object that acts as a monitor that checks the dictionary object after every n seconds. How can I do that ?

  • Using sleep in not an option since that blocks the main thread updating the dictionary
  • I tried using Timer, but that only runs once. How can I make this Timer run forever?

This is the code I use.

def monitor_data():
   print data_dict

global data_dict
t = Timer(10.0, monitor_data)
t.start()
silencer
  • 2,285
  • 5
  • 18
  • 18

2 Answers2

3

Doing CPython threading with one or more CPU-bound threads doesn't work well.

Jython threads fine, as does IronPython. And Pypy may soon become the best at threading, but for now, it's not great.

I'd suggest that if you're CPU-bound, you use multiprocessing instead: Python multiprocessing: How do I share a dict among multiple processes?

If 100% of your CPython threads are I/O bound and 0% are CPU-bound, you could thread effectively.

Community
  • 1
  • 1
dstromberg
  • 6,954
  • 1
  • 26
  • 27
  • 1. Even CPU-bound threads run *concurrently* in Python. Though there is no time performance benefit in this case if GIL is not release on CPython and even the degradation is possible 2. C extensions such as `regex`, `lxml`, `numpy` can release GIL – jfs Mar 27 '14 at 03:03
2

You have essentially two solutions. One solution might be to use a separate thread to print out the value of the dictionary. This solution would probably be the most similar to your attempted solution using the Timer. For example:

import threading
import time

class MonitoringThread(threading.Thread):
    def __init__(self, interval, dict):
        super(MonitoringThread, self).__init__()
        self._continue = True
        self._interval = interval
        self._dict = dict

    def stop(self):
        self._continue = False

    def run(self):
        while self._continue:
            print self._dict
            time.sleep(self._interval)


def main():
    data_dict = {'test': 0}

    t = MonitoringThread(10, data_dict)
    t.start()

    try:
        while True:
            time.sleep(1)   
            data_dict['test'] += 1  # Example update
    except:
        t.stop()

if __name__ == '__main__':
    main()

Alternatively, you could also try structuring your code so that it updates the dictionary in a loop, but only checks once 10 seconds has passed:

import time

def main():
    data_dict = {'test': 0}
    prev_time = time.time()
    while True:
        time.sleep(1)
        data_dict['test'] += 1

        if time.time() - prev_time >= 10:
            print data_dict
            prev_time = time.time()

if __name__ == '__main__':
    main()
Michael0x2a
  • 58,192
  • 30
  • 175
  • 224