2012-03-21 14 views
23

में मैं एक विधि लिखने की कोशिश कर रहा हूं जो किसी दिए गए समय पर गिना जाता है और जब तक कोई पुनरारंभ आदेश नहीं दिया जाता है, तो यह कार्य निष्पादित करेगा। लेकिन मुझे नहीं लगता कि पाइथन threading.Timer वर्ग टाइमर को रद्द करने योग्य होने की अनुमति देता है।कैंससेलबल थ्रेडिंग। पायथन

import threading 

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

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

    t.start() 

मुझे पता है कि उपरोक्त कोड किसी भी तरह गलत है। यहां पर किसी तरह के मार्गदर्शन की सराहना करेंगे।

उत्तर

12

मुझे यकीन नहीं है कि मैं सही ढंग से समझता हूं। क्या आप इस उदाहरण में कुछ लिखना चाहते हैं?

>>> 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() 
>>> 
+0

यह _almost_ अच्छा है। यह * अच्छा * होगा यदि आपका प्रोग्राम तत्काल समाप्त नहीं हुआ, एक "हैलो" के साथ और कोई देरी नहीं! :) आपको कुछ कंडिशन के आधार पर 'say.cello()' फ़ंक्शन में 't.cancel()' को शामिल करना होगा, उदा। 'अगर काउंटर == 10: टी.cancel()'। इसके बाद इसका अर्थ होगा। – Apostolos

+0

क्षमा करें। तब भी यह अच्छा नहीं होगा। यदि आप 'SayHello (0)' को कॉल करने के बाद कोई कोड जोड़ते हैं, तो टाइमर परीक्षण समाप्त होने से पहले इसे निष्पादित किया जाएगा! (अपने कोड के अंत में 'प्रिंट "हो गया" जोड़कर इसे स्वयं आज़माएं।) – Apostolos

25

आप विधि रद्द फोन आप टाइमर प्रारंभ करने के बाद होगा:

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() 

आप एक Thread पर थोड़ी देर के पाश का उपयोग कर के बजाय एक टाइमर उपयोग करने पर विचार हो सकता है।
यहाँ एक उदाहरण निकोलस ग्रेडवॉल के answer से एक और सवाल करने के लिए विनियोजित है:

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() 
+0

कृपया बताएं कि आप एक समय के साथ क्यों सोचते हैं कि लूप थ्रेड टाइमर की तुलना में बेहतर विचार है। –

+1

@ वेसमोड्स मैंने एक विकल्प पेश किया जो गिनती को प्रिंट करता है। –

+0

मेरे लिए काम करता है। हालांकि मैं गिनती चर के बजाय हर दूसरे को निष्पादित करने के लिए self.event.wait (1) नहीं करता था – mtosch

6

threading.Timer वर्ग एक cancel विधि है, और हालांकि यह धागा रद्द नहीं होगा, यह घड़ी बंद हो जाएगा वास्तव में फायरिंग से। वास्तव में क्या होता है कि cancel विधि threading.Event सेट करती है, और वास्तव में threading.Timer निष्पादित थ्रेड उस घटना को प्रतीक्षा करने के बाद और वास्तव में कॉलबैक निष्पादित करने से पहले जांच करेगा।

यह कहा गया है कि टाइमर आमतौर पर के बिना प्रत्येक के लिए एक अलग थ्रेड का उपयोग करके लागू किए जाते हैं। ऐसा करने का सबसे अच्छा तरीका यह है कि आपका प्रोग्राम वास्तव में क्या कर रहा है (इस टाइमर की प्रतीक्षा करते समय) पर निर्भर करता है, लेकिन एक घटना लूप के साथ कुछ भी, जैसे कि जीयूआई और नेटवर्क फ्रेमवर्क, सभी में ईवेंट टाइप में लगाए गए टाइमर का अनुरोध करने के तरीके हैं।

0

उपर्युक्त पोस्ट से प्रेरित। पायथन में रद्द करने योग्य और टाइमर रीसेट करना। यह धागा का उपयोग करता है।
विशेषताएं: प्रारंभ करें, रोकें, पुनरारंभ करें, कॉलबैक फ़ंक्शन।
इनपुट: टाइमआउट, sleep_chunk मान, और callback_function।
किसी भी अन्य कार्यक्रम में इस वर्ग का उपयोग या वारिस कर सकते हैं। कॉलबैक फ़ंक्शन में तर्क भी पास कर सकते हैं।
टाइमर को भी मध्य में जवाब देना चाहिए। पूर्ण नींद के समय के पूरा होने के बाद ही नहीं। तो नींद के छोटे हिस्सों का उपयोग करके, एक पूर्ण नींद का उपयोग करने के बजाय और लूप में ईवेंट ऑब्जेक्ट की जांच करना जारी रखा।

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() 
संबंधित मुद्दे