title: How to use threads with python circuits
body: <p>I've recently discovered the Circuits framework to build asynchronous apps in python. I am building an event driven application and this framework seems a good fit for my needs. The framework is based on the idea of Components which react when an Event is received. Great!! I followed the tutorial and I created some simple applications and every thing seemed to work properly until I tried to use a component to perform some heavy computation tasks. I know, the framework supports workers but I don't want to use workers. What I want to do is to run each component in a thread so that several components can be executed in parallel. The framework seems to support this modality by means of the <code>start</code> method. </p>
  
  <p>from the Component.py source code:</p>
  
  <pre><code>def start(self, process=False, link=None):
      """
      Start a new thread or process that invokes this manager's
      ``run()`` method. The invocation of this method returns
      immediately after the task or process has been started.
      """
  
      if process:
          # Parent&lt;-&gt;Child Bridge
          if link is not None:
              from circuits.net.sockets import Pipe
              from circuits.core.bridge import Bridge
  
              channels = (uuid(),) * 2
              parent, child = Pipe(*channels)
              bridge = Bridge(parent, channel=channels[0]).register(link)
  
              args = (child,)
          else:
              args = ()
              bridge = None
  
          self.__process = Process(
              target=self.run, args=args, name=self.name
          )
          self.__process.daemon = True
          self.__process.start()
  
          return self.__process, bridge
      else:
          self.__thread = Thread(target=self.run, name=self.name)
          self.__thread.daemon = True
          self.__thread.start()
  
          return self.__thread, None
  
  def join(self):
      if getattr(self, "_thread", None) is not None:
          return self.__thread.join()
  
      if getattr(self, "_process", None) is not None:
          return self.__process.join()
  </code></pre>
  
  <p>So I tried to implement the classic producer/consumer application using the <code>start</code> and <code>join</code> method showed previously. I would like that the producer and consumer run in their own thread and the main thread waits until they finish.</p>
  
  <pre><code>import time
  from threading import current_thread
  from circuits import Component, Event, Debugger
  
  
  class go(Event):
      """ go """
  
  class produced(Event):
      """ produced """
  
  class Consumer(Component):
  
      def started(self, *args):
          print(current_thread())
          print(current_thread().ident)
          print("Comuser started")
  
      def produced(self, *args):
          print("I am consuming...")
  
  class Producer(Component):
  
      def started(self, *args):
          print("Producer started")
          print(current_thread().ident)
  
      def go(self, *args):
          print("gooooooooooo")
          while True:
              self.fire(produced())
              print("Produced element, going to sleep for 1 sec")
              time.sleep(1)
  
  c = Consumer()
  c.start()
  p = Producer()
  p.start()
  
  p.fire(go())
  
  c.join()
  p.join()
  </code></pre>
  
  <p>Unfortunately, the above code doesn't work as expected. The app just exits as soon as the main code is executed. What's wrong in my code? If you know any example where this library is used in a similar fashion, could you provide me wiht a link? </p>
  
  <p>Thank you. </p>
  
  <p><a href="http://pythonhosted.org/circuits/" rel="nofollow">http://pythonhosted.org/circuits/</a>  </p>
  
  <hr>
  
  <p><strong>EDIT</strong></p>
  
  <p>After James's answer I tried a few more ways to run the components, but I still can't get them to run in parallel. </p>
  
  <p>Code:</p>
  
  <pre><code>c = Consumer()
  c.start()
  p = Producer()
  p.run()
  p.fire(go())
  </code></pre>
  
  <p>Output:</p>
  
  <pre><code>&lt;Thread(Consumer, started daemon 4334432256)&gt;
  4334432256
  Comuser started
  Producer started
  140735301485312
  </code></pre>
  
  <p>It looks like the app gets stuck. Then, I tried to use a main app component which kicks off the other components.</p>
  
  <p>Code:</p>
  
  <pre><code>class App(Component):
  
      def started(self, *args):
          print("App started")
          p.fire(go())
  
  (App() + Debugger()).run()
  </code></pre>
  
  <p>Output:</p>
  
  <pre><code>Comuser started
  Producer started
  4461318144
  &lt;registered[*] (&lt;Debugger/* 75445:MainThread (queued=0) [S]&gt;, &lt;App/* 75445:MainThread (queued=2) [R]&gt; )&gt;
  &lt;started[*] (&lt;App/* 75445:MainThread (queued=1) [R]&gt; )&gt;
  App started
  gooooooooooo
  Produced element, going to sleep for 1 sec
  Produced element, going to sleep for 1 sec
  Produced element, going to sleep for 1 sec
  Produced element, going to sleep for 1 sec
  Produced element, going to sleep for 1 sec
  Produced element, going to sleep for 1 sec
  Produced element, going to sleep for 1 sec
  Produced element, going to sleep for 1 sec
  Produced element, going to sleep for 1 sec
  Produced element, going to sleep for 1 sec
  Produced element, going to sleep for 1 sec
  Produced element, going to sleep for 1 sec
  Produced element, going to sleep for 1 sec
  Produced element, going to sleep for 1 sec
  ^C&lt;signal[*] (2, &lt;frame object at 0x7fe218725fa8&gt; )&gt;
  &lt;stopped[*] (&lt;App/* 75445:MainThread (queued=0) [S]&gt; )&gt;
  </code></pre>
  
  <p>It looks like only the producer is running... what I would like to see in the output is something like: </p>
  
  <pre><code>Produced...
  Consumed...
  Produced...
  Consumed...
  </code></pre>