1

I have multiple threads that run a while loop. I would like to terminate these threads after a given amount of time. I am aware of other questions similar to this but I don't see how I can transfer those answers to my code.

 def function1(arg1, arg2, arg3, duration):
        t_end = time.time() + duration
        while time.time() < t_end:
            #do some stuff

for i in range(100):
    t = Thread(target = function1, args=(arg1, arg2, arg3, 10))
    t.start()

This opens 100 threads but they never close. How can I close these threads after the specified time, in this example 10 seconds? My function opens a socket.

J.Doe
  • 97
  • 5
  • Your example has an undefined variable: `TIME`. Please provide a short complete program that we can run. Please say what the expected and actual outcome of your program is. See [mcve] and [ask] for more info. – Robᵩ Dec 29 '15 at 03:15
  • Sorry, that undefined variable TIME was meant to be duration, the question has been edited. Would you still like a short complete program? @Rob – J.Doe Dec 29 '15 at 03:19
  • Yes, an MCVE would still be helpful. It would demonstrate, for example, which `Thread` you are using, and precisely what you mean by "they never close." – Robᵩ Dec 29 '15 at 04:40
  • When I fill in the missing bits in your program, I get a program that lunches 100 threads, each of which exit after 10 seconds. After all of the threads have exited, the entire program exits. In other words, the code that you've shown so far works perfectly. Perhaps the problem is in the code you haven't shown us. See http://ideone.com/aeblek – Robᵩ Dec 29 '15 at 04:53
  • Your right the test program works. The problem might be that my function opens a socket. Could there be a reason for this? @Robᵩ – J.Doe Dec 29 '15 at 06:38

2 Answers2

1

Use a mixture of terminating a thread (info found here: Is there any way to kill a Thread in Python?)

and threading timer objects: https://docs.python.org/2/library/threading.html#timer-objects

The code below works for me, but the fact it keeps throwing a TypeError has got me puzzled. I can't seem to find much information on why it's happening or how to prevent it:

threadingtest.py

#!/usr/bin/env python3
import time
import threading

class StoppableThread(threading.Thread):
    """Thread class with a stop() method. The thread itself has to check
    regularly for the stopped() condition."""

    def __init__(self):
        super(StoppableThread, self).__init__()
        self._stop = threading.Event()

    def stop(self):
        self._stop.set()
        try:
            self.join()

        except TypeError as tE:
            print("Shutting down")

    def stopped(self):
        return self._stop.isSet()

class MyStoppableThread(StoppableThread):

    def __init__(self, *args):
        super(MyStoppableThread, self).__init__()
        self.args = args # Use these in the thread

    def run(self):
        print("Started my thread with arguments {}".format(self.args))
        while not self.stopped():
            time.sleep(1)
            # THIS IS WHERE YOU DO THINGS

if __name__ == "__main__":
    threads = []
    for i in range(100):
        t = MyStoppableThread(i, 'a', 'b', 'c')
        t.start()
        threads.append(t)

    print("\n:: all threads created\n")
    time.sleep(5)
    print("\n:: killing all threads\n");
    for t in threads:
        t.stop()
Community
  • 1
  • 1
NuclearPeon
  • 5,743
  • 4
  • 44
  • 52
1

You could pass a callback to each thread. And create a thread list.

threadlist  = {}
def cb(id, currtime):
    t = threadlist[id]
    d = currtime - t.starttime
    if d > 10:
        return True
    else:
        return False

def function1(arg1, arg2, arg3, duration, cb, threadid):
    t_end = time.time() + duration
    while time.time() < t_end:
        #do some stuff
        if cb(threadid, time.time()):
            break

for i in range(100):
    t = Thread(target = function1, args=(arg1, arg2, arg3, 10, cb, i))
    threadlist[id] = {"starttime": time.time(), "thread": t}
    t.start()

And to check:

time.sleep(15)
for item in threadlist.values():
    print(item.thread.is_alive())
jmunsch
  • 22,771
  • 11
  • 93
  • 114
  • This doesn't seem to work for my program. I believe the reason is that my function opens a socket. How would I fix this problem? – J.Doe Dec 29 '15 at 07:32
  • inside the while loop the program should be in the same context as the socket. So you could close it and then return instead of just break. I would need a fuller picture of the code to give you a better answer. – jmunsch Dec 29 '15 at 16:21