def __init__(self)self count self mutex thread allocate_lock(def incr(self)self mutex acquire(self count + self mutex release(def decr(self)self mutex acquire(self count - self mutex release(def __len__(self)return self count or use threading semaphore or with self mutextrue/false if used as flag ################################################################################self-test codesplit thread action into mainexitsprogress ################################################################################if __name__ ='__main__'self-test code when run import time or pp gui tour scrolledtext from tkinter scrolledtext import scrolledtext def onevent( )myname 'thread-%si startthreadaction threadactionargs ( )context (myname,)onexit threadexitonfail threadfailonprogress threadprogressthread' main action def threadaction(idrepsprogress)for in range(reps)time sleep( if progressprogress(iif id = raise exception code that spawns thread what the thread does progress callbackqueued odd numberedfail thread exit/progress callbacksdispatched off queue in main thread def threadexit(myname)text insert('end''% \texit\nmynametext see('end'def threadfail(exc_infomyname)text insert('end''% \tfail\ % \ (mynameexc_info[ ])text see('end'def threadprogress(countmyname)text insert('end''% \tprog\ % \ (mynamecount)text see('end'text update(works hererun in main thread make enclosing gui and start timer loop in main thread guisthreadsand queues