it-swarm.dev

Membatalkan threading.Timer dalam Python

Saya mencoba untuk menulis metode yang menghitung mundur ke waktu tertentu dan kecuali jika perintah restart diberikan, itu akan menjalankan tugas. Tapi saya tidak berpikir kelas Python threading.Timer memungkinkan timer dapat dibatalkan.

import threading

def countdown(action):
    def printText():
        print 'hello!'

    t = threading.Timer(5.0, printText)
    if (action == 'reset'):
        t.cancel()

    t.start()

Saya tahu kode di atas entah bagaimana salah. Akan menghargai beberapa panduan di sini.

30
Ted

Anda akan memanggil metode batal setelah memulai penghitung waktu:

import time
import threading

def hello():
    print "hello, world"
    time.sleep(2)

t = threading.Timer(3.0, hello)
t.start()
var = 'something'
if var == 'something':
    t.cancel()

Anda mungkin mempertimbangkan menggunakan while-loop pada Utas , daripada menggunakan Timer.
Berikut adalah contoh yang diambil dari answer Nikolaus Gradwohl untuk pertanyaan lain:

import threading
import time

class TimerClass(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.event = threading.Event()
        self.count = 10

    def run(self):
        while self.count > 0 and not self.event.is_set():
            print self.count
            self.count -= 1
            self.event.wait(1)

    def stop(self):
        self.event.set()

tmr = TimerClass()
tmr.start()

time.sleep(3)

tmr.stop()
30
Honest Abe

Saya tidak yakin apakah saya mengerti dengan benar. Apakah Anda ingin menulis sesuatu seperti dalam contoh ini?

>>> import threading
>>> t = None
>>> 
>>> def sayHello():
...     global t
...     print "Hello!"
...     t = threading.Timer(0.5, sayHello)
...     t.start()
... 
>>> sayHello()
Hello!
Hello!
Hello!
Hello!
Hello!
>>> t.cancel()
>>>
13
Adam

Kelas threading.Timer do memiliki metode cancel, dan meskipun tidak akan membatalkan thread , ia akan menghentikan timer agar tidak benar-benar menyala. Apa yang sebenarnya terjadi adalah metode cancel menetapkan threading.Event, dan utas yang benar-benar mengeksekusi threading.Timer akan memeriksa peristiwa itu setelah selesai menunggu dan sebelum benar-benar mengeksekusi callback.

Yang mengatakan, timer biasanya dilaksanakan tanpa menggunakan utas terpisah untuk masing-masing. Cara terbaik untuk melakukannya tergantung pada apa yang sebenarnya dilakukan program Anda (sambil menunggu timer ini), tetapi apa pun dengan loop peristiwa, seperti GUI dan kerangka kerja jaringan, semua memiliki cara untuk meminta timer yang terhubung ke eventloop.

7
Thomas Wouters

Terinspirasi oleh posting di atas ..__ Dibatalkan dan Reset Timer dengan Python. Ini menggunakan utas.
Fitur: Mulai, Berhenti, Mulai ulang, fungsi panggilan balik.
.__ Input: Batas waktu, nilai sleep_chunk, dan fungsi callback_fungsi.
Dapat menggunakan atau mewarisi kelas ini di program lain mana pun. Dapat juga meneruskan argumen ke fungsi panggilan balik.
Timer juga harus merespons di tengah. Bukan hanya setelah selesai waktu tidur penuh. Jadi, alih-alih menggunakan satu tidur penuh, gunakan potongan kecil tidur dan terus memeriksa objek acara dalam lingkaran.

import threading
import time

class TimerThread(threading.Thread):
    def __init__(self, timeout=3, sleep_chunk=0.25, callback=None, *args):
        threading.Thread.__init__(self)

        self.timeout = timeout
        self.sleep_chunk = sleep_chunk
        if callback == None:
            self.callback = None
        else:
            self.callback = callback
        self.callback_args = args

        self.terminate_event = threading.Event()
        self.start_event = threading.Event()
        self.reset_event = threading.Event()
        self.count = self.timeout/self.sleep_chunk

    def run(self):
        while not self.terminate_event.is_set():
            while self.count > 0 and self.start_event.is_set():
                # print self.count
                # time.sleep(self.sleep_chunk)
                # if self.reset_event.is_set():
                if self.reset_event.wait(self.sleep_chunk):  # wait for a small chunk of timeout
                    self.reset_event.clear()
                    self.count = self.timeout/self.sleep_chunk  # reset
                self.count -= 1
            if self.count <= 0:
                self.start_event.clear()
                #print 'timeout. calling function...'
                self.callback(*self.callback_args)
                self.count = self.timeout/self.sleep_chunk  #reset

    def start_timer(self):
        self.start_event.set()

    def stop_timer(self):
        self.start_event.clear()
        self.count = self.timeout / self.sleep_chunk  # reset

    def restart_timer(self):
        # reset only if timer is running. otherwise start timer afresh
        if self.start_event.is_set():
            self.reset_event.set()
        else:
            self.start_event.set()

    def terminate(self):
        self.terminate_event.set()

#=================================================================
def my_callback_function():
    print 'timeout, do this...'

timeout = 6  # sec
sleep_chunk = .25  # sec

tmr = TimerThread(timeout, sleep_chunk, my_callback_function)
tmr.start()

quit = '0'
while True:
    quit = raw_input("Proceed or quit: ")
    if quit == 'q':
        tmr.terminate()
        tmr.join()
        break
    tmr.start_timer()
    if raw_input("Stop ? : ") == 's':
        tmr.stop_timer()
    if raw_input("Restart ? : ") == 'r':
        tmr.restart_timer()
0
manohar