Elka
Elka

Reputation: 63

How to end animation after function completes

I am writing a simple program to keep an eye on a few Addresses.

I want a simple text cursor animation to run while the program does its thing. I've managed to do that. However, my problem is that after the function doing the scanning finishes the animation keeps going and won't stop until I hit the break key.

import os
import time
import sys
import itertools
import threading

hostname = [multiple site list]

def responder(hostname):
    while True:

      for item in hostname:

         response = os.system("ping -q -c 1 -n > /dev/null 2>&1 " + item)

         if response == 0:
            time.sleep(2)
         else:
            print item, 'is DOWN!'
            sys.exit()

def animate():
  for c in itertools.cycle(['|', '\'']):

    sys.stdout.write('\rscanning for bums > ' + c)
    sys.stdout.flush()
    time.sleep(0.1)

t = threading.Thread(target=animate)
t.start()

responder(hostname)

I know the code might be a little messy as I'm halfway through the project but any idea what it is I could change to make the animation stop when the responder function exits?

Upvotes: 1

Views: 270

Answers (1)

user3657941
user3657941

Reputation:

You need to pass a threading.Event to the animate function and set it when you want it to stop:

import os
import time
import sys
import itertools
import threading

hostname = ['bogus.org']

def responder(hostname, t, quit_flag):
    while True:
        for item in hostname:
            response = os.system("ping -q -c 1 -n %s >> /dev/null 2>&1" % item)
            if response == 0:
                time.sleep(2)
            else:
                quit_flag.set()
                t.join()
                print "%s is DOWN!" % item
                return

def animate(quit_flag):
    for c in itertools.cycle(['|', '\'']):
        if quit_flag.is_set():
            print ""
            break
        sys.stdout.write('\rscanning for bums %s > %s' % (quit_flag.is_set(), c))
        sys.stdout.flush()
        time.sleep(0.1)

quit_flag = threading.Event()
t = threading.Thread(target=animate, args=(quit_flag,))
t.daemon = True
t.start()

responder(hostname, t, quit_flag)

I modified your responder function so that it sets the quit flag, joins the animate thread, prints the message, and then returns. This guarantees that the animate thread is finished before the message is printed.

I realized that trying to use a regular variable does not work because only the value gets passed to the animate function. If you do not want to use a threading.Event, you can use a single element array or some other object that will get passed by reference.

Upvotes: 1

Related Questions