En esta receta se muestra cómo hacer para correr algo en otro thread o proceso con pocos cambios y cómo lograr comunicación entre ellos.
Notar que el pid de quién lanza doer es distinto al que imprime doer
Ejemplo con Multiprocessing
import os import sys from multiprocessing import Process from multiprocessing import Queue class Doer(Process): def __init__(self, queue, state=None): Process.__init__(self) self.queue = queue self.state = state def _do_on_start(self): print "doint stuff on start" print "state:", self.state print "pid:", os.getpid() print def _on_end(self): print "doint stuff on end" print "state:", self.state print "pid:", os.getpid() print def run(self): self._do_on_start() msg = None while msg is None or msg != "exit": # blocks here msg = self.queue.get() print "handling message", msg # do stuff here according to the message if msg == "ping": print "pong" elif isinstance(msg, tuple) and len(msg) == 2: action, value = msg if action == "set-state": self.state = value print "new state:", self.state elif msg != "exit": print "unknown message", msg print self._on_end() def demo(): queue = Queue() print "creating doer from process", os.getpid() doer = Doer(queue, 42) doer.start() queue.put("ping") queue.put("foo") queue.put(("set-state", "hola!")) queue.put("exit") doer.join() if __name__ == "__main__": demo()
corriendolo tenemos el resultado
Ejemplo con Threading
Para hacerlo andar con threading hay que solo cambiar de donde importamos las cosas, aquí esta la diferencia:
Notar que el pid de quién lanza doer es igual al que imprime doer.
diff controlled.py controlledthread.py 4,5c4,5 < from multiprocessing import Process < from multiprocessing import Queue --- > from threading import Thread as Process > from Queue import Queue
import os import sys from threading import Thread as Process from Queue import Queue class Doer(Process): def __init__(self, queue, state=None): Process.__init__(self) self.queue = queue self.state = state def _do_on_start(self): print "doint stuff on start" print "state:", self.state print "pid:", os.getpid() print def _on_end(self): print "doint stuff on end" print "state:", self.state print "pid:", os.getpid() print def run(self): self._do_on_start() msg = None while msg is None or msg != "exit": # blocks here msg = self.queue.get() print "handling message", msg # do stuff here according to the message if msg == "ping": print "pong" elif isinstance(msg, tuple) and len(msg) == 2: action, value = msg if action == "set-state": self.state = value print "new state:", self.state elif msg != "exit": print "unknown message", msg print self._on_end() def demo(): queue = Queue() print "creating doer from process", os.getpid() doer = Doer(queue, 42) doer.start() queue.put("ping") queue.put("foo") queue.put(("set-state", "hola!")) queue.put("exit") doer.join() if __name__ == "__main__": demo()