Reputation: 1174
I'm trying to separate my logic (function or task) from main loop. This function usually takes long time to run. In following example calculate()
function takes a lot of time to calculate self.time
variable.
In other words I want calculate()
to be called asynchronously. In every iteration first I would check if calculate()
is running, if not then call it. Secondly I would call show()
function in every iteration, no matter if calculate()
changed self.time
value.
import time
import datetime
class Clock:
def __init__(self):
self.time = None
def calculate(self):
time.sleep(3)
self.time = datetime.datetime.now()
def show(self):
print(f"{self.time.minute}:{self.time.second}")
def loop(self):
while True:
self.calculate() # this should be asynchronous
self.show() # this should be called every iteration
if __name__ == '__main__':
clock = Clock()
clock.loop()
Output:
36:9
36:12
36:15
36:18
This is not a wanted outcome. What I want:
36:9
...
36:9
36:9
36:12
...
36:12
36:15
36:15
36:15
...
36:15
36:18
36:18
...
36:18
How I've tried to solve this (this probably not the best solution, so future reader please check answers):
import time
import datetime
import threading
class Clock:
def __init__(self):
self.time = datetime.datetime.now()
self.__thread = None
def calculate(self):
time.sleep(3)
self.time = datetime.datetime.now() # race condition?
def show(self):
print(f"{self.time.minute}:{self.time.second}")
def loop(self):
while True:
if self.__thread is None or not self.__thread.is_alive():
self.__thread = threading.Thread(target=self.calculate)
self.__thread.start()
self.show()
if __name__ == '__main__':
clock = Clock()
clock.loop()
Program output is what I wanted. Is there any flaw in this solution? I can think only of race condition.
I am aware that's not the greatest description of this problem. If you could help me with editing this post with more searchable and specific vocabulary I would be grateful. If you have idea for better title please leave it in comments.
Upvotes: 0
Views: 92
Reputation: 406
I checked your code in my IDE, and it looks like exactly what you wanted using an acceptable approach. The only alternative solution I can think of is: 1) use a temp variable that goes up by one until it gets to 3 then reset. 2) similar idea but use time.nextTime = 3
to jump every 3 seconds and print current time.
Also, your first code solution seems to take some time to run is because it's waiting 3 seconds to show the time. And regarding race condition, that's not an issue since you're not using multiple threads at the same time in your second solution.
Upvotes: 1