Hi,
I'm a c++ guy trying to learn python. I'm trying to code something which models how a jukebox would work. The code I've attached simply adds numbers to a list on keypresses (enqueuing) and then other threads remove them (the player).
My problem goes like this: When I press a key the system works as it should. If I press a key twice quite quickly its still ok. However, if I push a key 3 times or more in quick succession then the third and later events which I think should get triggered don't.
My understanding of threads in python is very limited. In fact this is pretty much my first shot at python. There's clearly some important point I'm missing, ...what is it please?
import threading, random, time, Tkinter as tk, sys
# globals
# (locks, events and lists)
shortener_done = threading.Event()
list_lock = threading.Lock()
removing_lock = threading.Lock()
the_list = []
# system values
#
# keypress listener, can be made into a remote controll listener
#
def keypressListener(event):
if event.keysym == 'Escape':#
keyWin.destroy()
print 'exiting\n'
# harsh shutdown...
sys.exit(0)
else:
local_longener = longener()
local_longener.start()
#
# add an item to the list
#
class longener( threading.Thread ):
def __init__( self ):
threading.Thread.__init__(self)
def run( self ):
# generate a number
ran_num = random.randint(1,100)
# put it on the list
list_lock.acquire()
the_list.append(ran_num)
print 'Just appended: ' , ran_num , ' to the list... ', len(the_list)
# check to see if we just
if(len(the_list) == 1):
print 'starting shortener'
local_shortener = shortener()
local_shortener.start()
list_lock.release()
#
# remove and item from the list
#
class shortener( threading.Thread ):
def __init__( self ):
threading.Thread.__init__(self)
def run( self ):
# we only want one shortener running at a time..
removing_lock.acquire()
# get the value from the list (and shorten it too)
list_lock.acquire()
if(len(the_list) > 0):
value = the_list.pop(0)
print 'removing value: ' , value , ' from the list... ...' , len(the_list)
list_lock.release()
# do some time consuming stuff
time.sleep(2)
print 'removed value: ' , value , ' from the list...' , len(the_list)
else:
list_lock.release()
# signal that we're done
removing_lock.release()
print 'sending shortener done'
shortener_done.set()
shortener_done.clear()
#
# waits on event "shortener_done"
# calls a new shortener whenever the system
# goes idle and the list is non-empty
#
class sd_controller( threading.Thread ):
def __init__( self ):
threading.Thread.__init__(self)
def run( self ):
while(1):
# whenever a shortener is done, start a new one (perhaps)
shortener_done.wait()
list_lock.acquire()
if(len(the_list) > 0):
print 'making new shortener'
local_shortener = shortener()
local_shortener.start()
else:
print 'zero list'
list_lock.release()
# start the non-empty list listener
my_sd_cont = sd_controller()
my_sd_cont.start
# start a window and grab key presses
keyWin = tk.Tk()
print "Press a key (Escape key to exit):"
keyWin.bind_all('<Key>', keypressListener)
keyWin.mainloop()