import os, threading, Queue
def idmaker(aqueue):
while True:
u = hexlify(os.urandom(8)).decode('ascii')
aqueue.put(u)
idqueue = Queue.Queue(2)
t = threading.Thread(target=idmaker, args=(idqueue,))
t.daemon = True
t.start()
def idgetter():
return idqueue.get()
Queue is often the best way to synchronize threads in Python -- that's frequent enough that when designing a multi-thread system your first thought should be "how could I best do this with Queues". The underlying idea is to dedicate a thread to entirely "own" a shared resource or subsystem, and have all other "worker" threads access the resource only by gets and/or puts on Queues used by that dedicated thread (Queue is intrinsically threadsafe).
Here, we make an idqueue
with a length of only 2 (we don't want the id generation to go wild, making a lot of ids beforehand, which wastes memory and exhausts the entropy pool -- not sure if 2
is optimal, but the sweet spot is definitely going to be a pretty small integer;-), so the id generator thread will block when trying to add the third one, and wait until some space opens in the queue. idgetter
(which could also be simply defined by a top-level assignment, idgetter = idqueue.get
) will normally find an id already there and waiting (and make space for the next one!) -- if not, it intrinsically blocks and waits, waking up as soon as the id generator has placed a new id in the queue.