title: Multithreaded cv2.imshow() in Python does not work
body: <p>I have two cameras (using OpenNI, I have two streams per camera, handled by the same instance of the driver API) and would like to have two threads, each capturing data from each camera independently, i.e. for one instance of the driver API, say <code>cam_handler</code>, I have two streams <code>depth</code> and <code>rgb</code> per camera, say <code>cam_handler.RGB1_stream</code> and <code>cam_handler.DEPTH1_stream</code></p>
  <p>Here is the code for the same:</p>
  <pre><code>import threading
  
  def capture_and_save(cam_handle, cam_id, dir_to_write, log_writer, rgb_stream,
                       depth_stream, io):
      t = threading.currentThread()
      shot_idx = 0
      rgb_window = 'RGB' + str(cam_id)
      depth_window = 'DEPTH' + str(cam_id)
      while getattr(t, &quot;do_run&quot;, True):
          if rgb_stream is not None:
  
              rgb_array = cam_handle.get_rgb(rgb_stream)
              rgb_array_disp = cv2.cvtColor(rgb_array, cv2.COLOR_BGR2RGB)
              cv2.imshow(rgb_window, rgb_array_disp)
              cam_handle.save_frame('rgb', rgb_array, shot_idx, dir_to_write + str(cam_id + 1))
              io.write_log(log_writer[cam_id], shot_idx, None)
  
          if depth_stream is not None:
              depth_array = cam_handle.get_depth(depth_stream)
              depth_array_disp = ((depth_array / 10000.) * 255).astype(np.uint8)
              cv2.imshow(depth_window, np.uint8(depth_array_disp))
              cam_handle.save_frame('depth', depth_array, shot_idx, dir_to_write + str(cam_id + 1))
          shot_idx = shot_idx + 1
  
          key = cv2.waitKey(1)
          if key == 27:  # exit on ESC
              break
      print &quot;Stopping camera %d thread...&quot; % (cam_id + 1)
      return
  
  def main():
      # Setup camera threads
      cam_threads = []
      dir_to_write = &quot;some/save/path&quot;
      for cam in range(cam_count):
          cam = (cam + 1) % cam_count
          cv2.namedWindow('RGB' + str(cam))
          cv2.namedWindow('DEPTH' + str(cam))
          one_thread = threading.Thread(target=capture_and_save,
                                        name=&quot;CamThread&quot; + str(cam + 1),
                                        args=(cam_cap, cam, dir_to_write,
                                              log_writer,
                                              rgb_stream[cam], depth_stream[cam], io,))
          cam_threads.append(one_thread)
          one_thread.daemon = True
          one_thread.start()
  
          try:
              while True:
                  pass
                  # cv2.waitKey(1)
          except KeyboardInterrupt:
              # Stop everything
              for each_thread in cam_threads:
                  each_thread.do_run = False
                  each_thread.join(1)
              cam_cap.stop_rgb(rgb_stream)
              cam_cap.stop_depth(depth_stream)
  
              # Stop and quit
              openni2.unload()
              cv2.destroyAllWindows()
  
  if __name__ == '__main__':
      main()      
  </code></pre>
  <p>So, my issue is that if I remove the <code>cv2.imshow()</code> lines from the code, everything runs as expected and I get both camera outputs saved to file. However, with the <code>cv2.imshow()</code> lines, there are only &quot;blank&quot; windows being created and the threads seem to be &quot;stuck&quot;, with no output at all.<br />
  I have tried several suggestions, including moving the <code>namedWindow</code> creation to the main thread as well as into the <code>capture_and_save</code> thread. I have also tried moving around the <code>waitKey()</code> because it was said that OpenCV only allows <code>waitKey()</code> in the main thread. There was no difference, however.</p>