0

I have a background thread that main calls, the background thread can open a number of different scripts but occasionally it will get an infinite print loop like this.

In thing.py import foo

def main():
    thr = Thread(target=background)
    thr.start()
    thread_list.append(thr)

def background():
    getattr(foo, 'bar')()
    return

And then in foo.py

def bar():
    while True:
        print("stuff")

This is what it's supposed to do but I want to be able to kill it when I need to. Is there a way for me to kill the background thread and all the functions it has called? I've tried putting flags in background to return when the flag goes high, but background is never able to check the flags since its waiting for bar to return.

EDIT: foo.py is not my code so I'm hesitant to edit it, ideally I could do this without modifying foo.py but if its impossible to avoid its okay

Indigo
  • 962
  • 1
  • 8
  • 23
  • Possible duplicate of [How to stop a looping thread in Python?](https://stackoverflow.com/questions/18018033/how-to-stop-a-looping-thread-in-python) – haronaut Oct 13 '17 at 15:11

1 Answers1

1

First of all it is very difficult (if possible) to control threads from other threads, no matter what language you are using. This is due to potential security issues. So what you do is you create a shared object which both threads can freely access. You can set a flag on it.

But luckily in Python each thread has its own Thread object which we can use:

import foo

def main():
    thr = Thread(target=background)
    thr.exit_requested = False
    thr.start()
    thread_list.append(thr)

def background():
    getattr(foo, 'bar')()
    return

And in foo:

import threading

def bar():
    th = threading.current_thread()
    # What happens when bar() is called from the main thread?
    # The commented code is not thread safe.
    # if not hasattr(th, 'exit_requested'):
    #     th.exit_requested = False
    while not th.exit_requested:
        print("stuff")

Although this will probably be hard to maintain/debug. Treat it more like a hack. Cleaner way would be to create a shared object and pass it around to all calls.

freakish
  • 54,167
  • 9
  • 132
  • 169
  • Thank you. Do you mind explaining where the thread.current_thread() comes from and how to pass the thr.exit_requested to another file? I've tried to implement this code and I can't quite get it to work – Indigo Oct 13 '17 at 16:26
  • @Indigo My bad, it was a typo. I've updated the code (you need `import threading`). Also `exit_requested` is set in `main`. – freakish Oct 13 '17 at 16:42