multithreading - Python Threading - Managing thread termination and the main thread -
before read on, know i'm new python , new threading forgive me if misunderstand how threads work or make rookie error :p
short description of goal:
- the main thread (a) things (e.g. prints "begin!")
- main thread spawns new thread (b) first prints "thread b started" , prints x+1 forever (1, 2, 3 ...)
- main thread prints "woop!"
- then end of main thread reached, terminates , switches thread b making b main thread
- program running thread b main thread printing x+1 forever , has been forgotten , no longer relevant
- ctrl+c terminate thread b , effectively, whole program terminated because thread doesn't exist anymore
here's have far (the basics):
import threading, time def printcount(): print "thread b started" x = 0 while true: time.sleep(1) x = x + 1 print x ## user code ## print "begin!" threadb = threading.thread(target=printcount) threadb.start() print "woop!"
the requirements are:
- i don't want modify below 'user code' mark @ all. don't want wrap in class, function or it's own thread
- pressing ctrl+c @ point should terminate entire program no threads left running (using like:
except
inside user code fine
keyboardinterrupt: os._exit(1)) - thread may continue run instead of making thread b main thread, in case, don't want code handle ctrl+c terminating entire program inside user code section
this example not actual goal, simplified version of problem i'm having. i'm trying make irc framework user can import , use api without messying own code threads , interrupts , like. why it's important user code clean possible.
the framework allow user create irc bot runs forever, listening commands whilst allowing user add own commands. github link here if you're interested (it's wip atm).
you cannot "switch" threads. once you're done main thread, have wait other threads terminate using method join
. note this:
- since
join
method not interruptiblekeyboardinterrupt
, need specify timeout , loop on detect user interrupts. - since can't force thread terminate, have implement stop mecanism using threading.event instance
- you need use threading.lock prevent concurrent access on shared resources,
sys.stdout
(used when print)
i gathered these aspects in class called threadhandler
, please have look:
import threading, time def printcount(lock, stop): lock: print "thread b started" x = 0 while not stop.is_set(): time.sleep(1) x = x + 1 lock: print x class threadhandler(): step = 0.2 def __init__(self, target): self.lock = threading.lock() self.stop = threading.event() args = (self.lock, self.stop) self.thread = threading.thread(target=target, args=args) def start(self): self.thread.start() def join(self): while self.thread.is_alive(): try: self.thread.join(self.step) except keyboardinterrupt: self.stop.set() ## user code ## print "begin!" handler = threadhandler(target=printcount) handler.start() handler.lock: print "woop!" handler.join()
Comments
Post a Comment