Reputation: 6548
I am trying to implement a small garden example.
Garden is a class that has grow()
function, which checks the amount of water supplied every second. When the amount of water is more than some threshold, garden produces a few flowers.
Here is my first try:
Garden class
import time
class Garden:
def __init__(self):
self.water = 0
print("Garden built!")
def grow(self):
while self.water < 50:
print("Water supplied: {0}".format(self.water))
time.sleep(1)
print("Produced 5 flowers!")
main.py
import time
from garden import Garden
from threading import Thread
from queue import Queue
def main():
que = Queue()
garden = Garden()
thr = Thread(target=garden.grow).start()
que_garden = que.get()
water(que_garden, 20)
time.sleep(5)
water(que_garden, 30)
thr.join()
def water(garden, amount):
garden.water += amount
print("Watered with {0}!".format(amount))
When I run main.py
I get the following input:
Garden built!
Water supplied: 0
Water supplied: 0
Water supplied: 0
Water supplied: 0
Water supplied: 0
So, grow()
gets constantly called and never gets to water(que_garden, 20)
line. I expected that once thr = Thread(target=garden.grow).start()
is called it is not locked until grow()
finishes but continues to the next line. What am I missing here?
Upvotes: 1
Views: 51
Reputation: 85582
This:
que_garden = que.get()
blocks until there is something in the queue. But there is no que_garden.put()
anywhere.
This works without a queue:
import time
from garden import Garden
from threading import Thread
def main():
garden = Garden()
thr = Thread(target=garden.grow)
thr.start()
water(garden, 20)
time.sleep(5)
water(garden, 30)
time.sleep(5)
water(garden, 10)
thr.join()
def water(garden, amount):
garden.water += amount
print("Watered with {0}!".format(amount))
main()
Output:
Garden built!
Water supplied: 0
Watered with 20!
Water supplied: 20
Water supplied: 20
Water supplied: 20
Water supplied: 20
Watered with 30!
Produced 5 flowers!
Watered with 10!
Upvotes: 1
Reputation: 10961
From Python Documentation:
class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
This constructor should always be called with keyword arguments. Arguments are:group should be None; reserved for future extension when a ThreadGroup class is implemented.
target is the callable object to be invoked by the run() method. Defaults to None, meaning nothing is called.
So, Change:
thr = Thread(target=garden.grow()).start()
to
thr = Thread(target=garden.grow).start()
Upvotes: 0
Reputation: 59623
I think that you want garden.grow
instead of garden.grow()
. The target parameter is a callable. You are calling the grow
method and passing its return value.
Upvotes: 1