title: Python Subprocess readline() hangs; can't use normal options
body: <p>To start, I'm aware this looks like a duplicate.  I've been reading:</p>
  
  <p><a href="https://stackoverflow.com/questions/12419198/python-subprocess-readlines-hangs">Python subprocess readlines() hangs</a></p>
  
  <p><a href="https://stackoverflow.com/questions/40963927/python-subprocess-readline-hangs-after-reading-all-input">Python Subprocess readline hangs() after reading all input</a></p>
  
  <p><a href="https://stackoverflow.com/questions/7897202/subprocess-readline-hangs-waiting-for-eof">subprocess readline hangs waiting for EOF</a></p>
  
  <p>But these options either straight don't work or I can't use them.</p>
  
  <h1>The Problem</h1>
  
  <pre><code># Obviously, swap HOSTNAME1 and HOSTNAME2 with something real
  cmd = "ssh -N -f -L 1111:&lt;HOSTNAME1&gt;:80 &lt;HOSTNAME2&gt;"
  
  p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=os.environ)
  while True:
      out = p.stdout.readline()
      # Hangs here ^^^^^^^ forever
  
      out = out.decode('utf-8')
      if out:
          print(out)
      if p.poll() is not None:
          break
  </code></pre>
  
  <p>My dilemma is that the function calling the <code>subprocess.Popen()</code> is a library function for running bash commands, so it needs to be very generic and has the following restrictions:</p>
  
  <ul>
  <li>Must display output as it comes in; not block and then spam the screen all at once</li>
  <li>Can't use multiprocessing in case the parent caller is multiprocessing the library function (Python doesn't allow child processes to have child processes)</li>
  <li>Can't use <code>signal.SIGALRM</code> for the same reason as multiprocessing; the parent caller may be trying to set their own timeout</li>
  <li>Can't use third party non-built-in modules</li>
  <li>Threading straight up doesn't work.  When the <code>readline()</code> call is in a thread, <code>thread.join(timeout=1)</code>lets the program continue, but <strong>ctrl+c</strong> doesn't work on it at all, and calling <code>sys.exit()</code> doesn't exit the program, since the thread is still open.  And as you know, you can't kill a thread in python by design.</li>
  <li>No manner of bufsize or other subprocess args seems to make a difference; neither does putting readline() in an iterator.</li>
  </ul>
  
  <p>I would have a workable solution if I could <strong>kill a thread</strong>, but that's super taboo, even though this is definitely a legitimate use case.</p>
  
  <p>I'm open to any ideas.</p>