title: Threads in twisted... how to use them properly?
body: <p>I need to write a simple app that runs two threads:
  - thread 1: runs at timed periods, let's say every 1 minute
  - thread 2: just a 'normal' while True loop that does 'stuff'</p>
  
  <p>if not the requirement to run at timed interval I would have not looked at twisted at all, but simple sleep(60) is not good enough and construction like:</p>
  
  <pre><code>l = task.LoopingCall(timed_thread)
  l.start(60.0)
  reactor.run()
  </code></pre>
  
  <p>Looked really simple to achieve what I wanted there.</p>
  
  <p>Now, how do I 'properly' add another thread?</p>
  
  <p>I see two options here:</p>
  
  <ul>
  <li>Use threading library and run two 'python threads' one executing my while loop, and another running reactor.run(). But Google seems to object this approach and suggests using twisted threading</li>
  <li>Use twisted threading. That's what I've tried, but somehow this looks bit clumsy to me.</li>
  </ul>
  
  <p>Here's what I came up with:</p>
  
  <pre><code>def timed_thread():
      print 'i will be called every 1 minute'
      return
  
  def normal_thread():
      print 'this is a normal thread'
      time.sleep(30)
      return
  
  l = task.LoopingCall(timed_thread)
  l.start(60.0)
  reactor.callInThread(normal_thread)
  reactor.run()
  </code></pre>
  
  <p>That seems to work, but! I can't stop the app. If I press ^C it wouldn't do anything (without 'callInThread' it just stops as you'd expect it to). ^Z bombs out to shell, and if I then do 'kill %1' it seems to kill the process (shell reports that), but the 'normal' thread keeps on running. kill PID wouldn't get rid of it, and the only cure is kill -9. Really strange.</p>
  
  <p>So. What am I doing wrong? Is it a correct approach to implement two threads in twisted? Should I not bother with twisted? What other 'standard' alternatives are to implement timed calls? ('Standard' I mean I can easy_install or yum install them, I don't want to start downloading and using some random scripts from random web pages).</p>