开发者

Stopping a thread after a certain amount of time

I'm looking to terminate some threads after a certain amount of time. These threads will be running an infinite while loop and during this time they can stall for a random, large amount of time. The thread cannot last longer than time set by the duration variable. How can I make it so after the length set by duration, the threads stop.

def main():
    t1 = threading.Thread(target=thread1, args=1)
    t2 = threading.Thread(target=thread2, args=2)

    time开发者_如何转开发.sleep(duration)
    #the threads must be terminated after this sleep


This will work if you are not blocking.

If you are planing on doing sleeps, its absolutely imperative that you use the event to do the sleep. If you leverage the event to sleep, if someone tells you to stop while "sleeping" it will wake up. If you use time.sleep() your thread will only stop after it wakes up.

import threading
import time

duration = 2

def main():
    t1_stop = threading.Event()
    t1 = threading.Thread(target=thread1, args=(1, t1_stop))

    t2_stop = threading.Event()
    t2 = threading.Thread(target=thread2, args=(2, t2_stop))

    time.sleep(duration)
    # stops thread t2
    t2_stop.set()

def thread1(arg1, stop_event):
    while not stop_event.is_set():
        stop_event.wait(timeout=5)

def thread2(arg1, stop_event):
    while not stop_event.is_set():
        stop_event.wait(timeout=5)


If you want the threads to stop when your program exits (as implied by your example), then make them daemon threads.

If you want your threads to die on command, then you have to do it by hand. There are various methods, but all involve doing a check in your thread's loop to see if it's time to exit (see Nix's example).


If you want to use a class:

from datetime import datetime,timedelta

class MyThread(): 

    def __init__(self, name, timeLimit):        
        self.name = name
        self.timeLimit = timeLimit
    def run(self): 
        # get the start time
        startTime = datetime.now()
    
        while True:
           # stop if the time limit is reached :
           if((datetime.now()-startTime)>self.timeLimit):
               break
           print('A')

mt = MyThread('aThread',timedelta(microseconds=20000))
mt.run()


An alternative is to use signal.pthread_kill to send a stop signal. While it's not as robust as @Nix's answer (and I don't think it will work on Windows), it works in cases where Events don't (e.g., stopping a Flask server).

test.py

from signal import pthread_kill, SIGTSTP
from threading import Thread

import time

DURATION = 5


def thread1(arg):
    while True:
        print(f"processing {arg} from thread1...")
        time.sleep(1)


def thread2(arg):
    while True:
        print(f"processing {arg} from thread2...")
        time.sleep(1)


if __name__ == "__main__":
    t1 = Thread(target=thread1, args=(1,))
    t2 = Thread(target=thread2, args=(2,))

    t1.start()
    t2.start()
    time.sleep(DURATION)
    # stops all threads
    pthread_kill(t2.ident, SIGTSTP)

result

$ python test.py
processing 1 from thread1...
processing 2 from thread2...
processing 1 from thread1...
processing 2 from thread2...
processing 1 from thread1...
processing 2 from thread2...
processing 1 from thread1...
processing 2 from thread2...
processing 1 from thread1...
processing 2 from thread2...

[19]+  Stopped                 python test.py
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜