Good afternoon everyone!
I am trying to do a class exercise using Condition(), Notifiy(), Acquire() and Release(), in which I am asked for the following:
- I create 20 threads from "main"
- Each thread must access a "drinkFromVaso" function.
- If they can drink, they drink for a while (between 1 and 10 seconds) and if not, they wait 0.5 seconds until they can try again
- When they finish drinking, they notify him and the next one enters
I've spent hours searching the web and watching videos and I just can't understand how it works. I have tried to do it with a "producer" and a "consumer" function, but when faced with...
with cond:
cond.wait() o cond.notify()
...I do not understand anything. And I don't even know if that's the way, because the statement doesn't make me understand that I should create two functions (not even a "producer" thread), but only the one to drink from the glass.
If someone could explain all this to me it would be wonderful.
The little I have so far is this, because I'm trying and trying...
import threading
import time
from random import randint
cond = threading.Condition()
def beber():
global cond
s = randint(1, 10)
print(f'El hilo {threading.currentThread().getName()} empina el codo duante {s} segundos')
time.sleep(s)
cond.notify()
print('Algo perjudicado, el hilo {} se retira'.format(threading.current_thread().name))
cond.release()
def controlDeAccesoAlBar():
global cond
while not (cond.acquire()):
cond.wait(0.5)
else:
beber()
def ejercicio4():
hilos = []
for i in range(20):
t = threading.Thread(target=controlDeAccesoAlBar(), name=('t' + str(i + 1)))
hilos.append(t)
t.start()
for i in range(len(hilos)):
hilos[i].join()
print('¡El bar cierra!')
Regards, and thank you very much!
All the action is in the show
beberDelVaso
.The function
Condition.acquire(blocking=True, timeout=-1)
has two ways of operating: with lock or without lock:When called with
acquire(True)
, the function blocks and does not return until it acquires thelock
.When called with
acquire(False)
, the function returns immediately, with a resultTrue
if it was able to acquire thelock
orFalse
, otherwise.To wait until we get the glass, we use
acquire(False)
. If the , could not be obtainedlock
, the function returnsFalse
and there we can wait 0.5 seconds before the next attempt.notify
The other or functions are not needed for this exercisewait
, since each thread is independent and does not produce or consume anything from the other threads.The rest of the code remains the same:
show
Despite having marked CandidMoe's answer as good, I'm also going to post the one my teacher finally told me. Either one works fine, but in the exercise I was doing I was expected to use wait() and therefore notify().
I hope it will be useful to someone in the future.
I'm guessing, although this is just a guess, that CandidMoe's answer doesn't put the thread into a "wait" state, while wait() does.
I also come to leave my own solution. I thought it was a fun problem and it helped me to learn more about threading. I hope that someone can be useful in case you do not understand or do not serve the previous answers. I also leave another good example that can be used to learn more about how this library works Example SO
I reduced the time range from 1-10 seconds to 1-3 seconds and the number of threads from 20 to 5.
Output