1

I would like to ask: how to write a python program to calculate 1 hour has been passed since we started a python program?

I take an example: - We started the python program at 17:00:00 - After running 1 hour (at 18:00:00), python program will print a message to inform 1 hour has been passed.

I can figure out a python program. Firstly, I record the time at starting the program (called start_time), then I continuously record the next time (called end_time). If the (end_time - start_time == 1 hour), it prints a message.

However it seems the program wastes so much CPU performance! I need a program that take less CPU performance.

EDIT: I need as below.

I have a thread name wait_an_event_thread. It is a blocking thread. If event trigger is not set, this thread is blocked. During blocking time, if 1 hour has been passed, this thread print out a message. That is my expectation.

Previously, I said that I continuously record next time (call end_time). It meant I intended change from blocking thread to non-blocking thread because I did not know how to print a message in blocked thread if 1 hour has been passed. But it seems non-blocking thread take so much CPU performance.

This is my code:
MY EXPECTATION: blocking thread

def wait_an_event_thread(trigger):
    trigger.wait()
    # If 1 hour has been passed, it print a message
    # How to print message if 1 hour has been passed in this blocking thread if the "trigger" event is not set??

trigger  = threading.Event()
wait_an_event_thread = threading.Thread(name='wait_an_event_thread', 
                       target=wait_an_event_thread,
                       args=(trigger,))
wait_an_event_thread.start()
jackbk
  • 123
  • 1
  • 1
  • 9
  • 4
    You could use a [`Timer`](https://docs.python.org/3/library/threading.html?highlight=timer#threading.Timer). You also should include a minimal example of what you've tried up till now, so others can better help you. – Ilja Everilä May 30 '17 at 10:35
  • I edit my post for my example. Could you read it? – jackbk May 30 '17 at 11:26
  • You have a function and a var with the same name, it causes problems. Also, if you want her help you need to tag her as so @IljaEverilä – Isdj May 30 '17 at 11:48
  • I'm afraid I don't understand what you mean by a blocking thread. Is the trigger an event, condition, or other synchronization object that the thread should wait for (as it seems to do), but it should resume after an hour has passed to inform about it. What should happen after that? Should it continue to wait? Should the program exit? For example `Event.wait()` accepts a timeout as float seconds, after which it resumes even if the flag has not been set. – Ilja Everilä May 30 '17 at 12:14
  • Are you perhaps looking for something like `while not trigger.wait(timeout=3600):` + the print inside the loop (if using an `Event`)? In other words: what is `trigger`? – Ilja Everilä May 30 '17 at 12:20
  • @IljaEverilä: "blocking thread" means a thread will be blocked until an event is set. In my example, `trigger` is an event and `wait_an_event_thread` is a thread. `wait_an_event_thread` thread must wait for `trigger` event is set. If `trigger` event is not set, the thread will be blocked. `trigger` event has no timeout, so if the blocking time is more than 1 hour without a message printed, it is not my expectation. – jackbk May 31 '17 at 02:34
  • @IljaEverilä: Do we have any mechanism to make the thread still wait for `trigger` event, but the thread can issue a print message after waiting 1 hour?After issuing the message, it continues waiting for `trigger` event. I need the `trigger` event has no timeout of waiting. – jackbk May 31 '17 at 02:40
  • What's your python version? `Event.wait()` has had the optional *timeout* parameter since 2.4 at least. Whether or not it returns the flag state when it resumes changed in 2.7. Before that it would always return None. There's a [potential pitfall if clock changes while it's waiting](https://stackoverflow.com/a/35633484/2681632), but that might or might not affect you. – Ilja Everilä May 31 '17 at 05:45
  • @IljaEverilä: I am using Python version Python 2.7.9. I knew that `Event.wait()` has _timeout_ parameter, but my program need to use `Event.wait()` with no timeout. In other words, my `wait_an_event_thread` thread wait for `trigger` event until `trigger` event is set (no time limitation of waiting, ex. 2 hours, 3 hours,..). During waiting for `trigger` event, if 1 hour has been passed since the thread `wait_an_event_thread` started, I need to do something (now I need to print a message). Can we have any mechanism to do this? – jackbk May 31 '17 at 06:32
  • Yes. Use the timeout. If it wakes up because there was a timeout (`wait()` returns False), print the diagnostic message and then resume waiting. The simple `while not trigger.wait(3600): print "..."` will handle that, with the potential issues if your clock changes. – Ilja Everilä May 31 '17 at 06:38
  • @IljaEverilä: It works. I will take care my clock changes. Thank you so much. – jackbk May 31 '17 at 10:01

5 Answers5

4
import threading

def func():
    #your code here

t = threading.Timer(3600, func)
t.start()

More details in documentation

Thanks to @Ilja Everilä for the corrections and improvements

Isdj
  • 1,835
  • 1
  • 18
  • 36
  • Use seconds for compare hours ? Don't need seconds level resolution ! – dsgdfg May 30 '17 at 10:53
  • Any programmer never use an external timer ! How to handle garbage data, exceptions, errors etc. Function time not equal to system time. What is event ? – dsgdfg May 30 '17 at 10:59
  • 3
    @dsgdfg You make 0 sense to me. Python handles garbage collection as it always does. Handle exceptions in the callback function. Time skew is a topic on its own. – Ilja Everilä May 30 '17 at 11:01
  • 3
    @dsgdfg it is a built in module... If you manage to use python without using any modules you are either an extremely good programmer with a ton of time or you have no code other than 'hello world' – Isdj May 30 '17 at 11:02
  • Thank you for Timer suggestion. But I need to calculate 1 hour passed inside a blocking thread. Could you check my edited post? – jackbk May 30 '17 at 11:28
  • I don't understand what you mean by blocking thread. Blocking a thread is just putting it to sleep with time.sleep(seconds) – Isdj May 30 '17 at 11:45
  • @IsaacDj: Blocking thread means the thread must wait for `trigger` event without timeout (we can define a timeout for an event, ex. 1 hour, but I need `trigger` event wait with no timeout). During wait `trigger` event, can we print a message if 1 hour has been passed? I also posted the detail at the answer for @IljaEverilä – jackbk May 31 '17 at 02:44
1

As it turned out you needed to use the timeout parameter of Event.wait() and check if the event has been set upon return or not:

def wait_an_event_thread(trigger):
    while not trigger.wait(3600):
        print "1 hour has passed"

    # Do what must be done when triggered

trigger = threading.Event()
the_thread = threading.Thread(name='wait_an_event_thread', 
                              target=wait_an_event_thread,
                              args=(trigger,))
the_thread.start()

This'll keep on printing the diagnostic message between hour(ish) intervals, if the Event is not set. Event.wait() might behave badly if your system clock jumps backwards.

Ilja Everilä
  • 50,538
  • 7
  • 126
  • 127
0

You could take advantage of multi-threading and create a separate thread that runs separately from the rest of the code. That thread simply sleeps for 1h and then prints "1h have been passed" then sleeps again for another hour.

To put it in code form, you will need something like this:

import time
def print_message_every_interval( threadName, message, interval=3600, ):
   while True:
      time.sleep(interval) #interval in seconds
      print ("%s: %s: %s" % ( threadName, time.ctime(time.time()), message ))

and in your main() add something like:

  import _thread

  if __name__=="__main__":
   #
   # your init code here
   #
   try:
    _thread.start_new_thread( print_message_every_interval, \
     ("Timer-1h", "One hour have passed", 3600 ) )
   except Exception as e:
    print('could not start new thread')
    print(e)
   #
   # the rest of your code here
   #

of course there are many multi-threading libraries you can use to make the code look fancy. Like the threading module.

You can find more on this topic here: https://www.tutorialspoint.com/python3/python_multithreading.htm

Ouss
  • 2,912
  • 2
  • 25
  • 45
0

I suggest after one hour you use

`time.sleep(t)` 

where t being as high as possible without affecting your program.

0

start a thread which will call a function after every hour and print message. you can write the code like this with your main function: import threading

def print():
    print "One Hour has been passed"

t = threading.Timer(3600, print)
t.start()

This will call the print function after every hour and print the message.

suraj
  • 403
  • 4
  • 15
  • Shouldn't use builtin names – Isdj May 30 '17 at 10:56
  • `def print(): print...` Try and run this on Python 3, having corrected `print ""` into `print("")`, and you'll understand why you never overwrite built-in names ;) – Right leg May 31 '17 at 10:32