title: EOFError while using Pipe with multiprocessing in python
body: <p>I'm trying to use the multiprocessing model to speed up the rate of detection for a model. I want to use four cores and process images in a parallel fashion while keeping them in order. When a process is spawned, a pipe is instantiated as well, the child portion is passed to the process while the parent is kept in a separate queue. The script throws an EOFError as I call the recv method on parent pipe even after I polled the pipe.</p>
  <p>In a simpler version of this program, I simply sent &quot;hello&quot; instead of the image, but an EOFError was still thrown. Also, I tried the script with and without closing the child end of the pipe but the error was still thrown</p>
  <pre><code>import io 
  import time
  import tensorflow as tf
  physical_devices = tf.config.experimental.list_physical_devices('GPU')
  if len(physical_devices) &gt; 0:
      tf.config.experimental.set_memory_growth(physical_devices[0], True)
  from absl import app, flags, logging
  import core.utils as utils
  from core.yolov4 import filter_boxes
  from tensorflow.python.saved_model import tag_constants
  from PIL import Image
  import cv2
  import numpy as np
  from tensorflow.compat.v1 import ConfigProto
  from tensorflow.compat.v1 import InteractiveSession
  from queue import Queue 
  from concurrent.futures import ProcessPoolExecutor
  from multiprocessing import Pool, Process, Pipe
  
  flag_rep = {
      &quot;framework&quot; : 'tflite',
      &quot;weights&quot; : './checkpoints/yolov4-tiny-416.tflite',
      &quot;size&quot; : 416,
      &quot;tiny&quot; : False,
      &quot;model&quot; : 'yolov4',
      &quot;iou&quot; : .45,
      &quot;score&quot; : .25,
  }
  vid = cv2.VideoCapture(0)
  config = ConfigProto()
  config.gpu_options.allow_growth = True
  
  session = InteractiveSession(config=config)
  STRIDES, ANCHORS, NUM_CLASS, XYSCALE = utils.load_config_from_dict(flag_rep)
  input_size = flag_rep['size']
  interpreter = tf.lite.Interpreter(model_path=flag_rep['weights'])
  interpreter.allocate_tensors()
  input_details = interpreter.get_input_details()
  output_details = interpreter.get_output_details()
  i=0
  
  def eval_im(frame, child):
      original_image = frame
      original_image = cv2.cvtColor(original_image, cv2.COLOR_BGR2RGB)
      image_data = cv2.resize(original_image, (input_size, input_size))
      image_data = image_data / 255.
      images_data = []
      for i in range(1):
          images_data.append(image_data)
      images_data = np.asarray(images_data).astype(np.float32)
      interpreter.set_tensor(input_details[0]['index'], images_data)
      interpreter.invoke()
      pred = [interpreter.get_tensor(output_details[i]['index']) for i in range(len(output_details))]
      boxes, pred_conf = filter_boxes(pred[0], pred[1], score_threshold=0.25, input_shape=tf.constant([input_size, input_size]))
      boxes, scores, classes, valid_detections = tf.image.combined_non_max_suppression(
          boxes=tf.reshape(boxes, (tf.shape(boxes)[0], -1, 1, 4)),
          scores=tf.reshape(
              pred_conf, (tf.shape(pred_conf)[0], -1, tf.shape(pred_conf)[-1])),
          max_output_size_per_class=50,
          max_total_size=50,
          iou_threshold=flag_rep['iou'],
          score_threshold=flag_rep['score']
      )
      pred_bbox = [boxes.numpy(), scores.numpy(), classes.numpy(), valid_detections.numpy()]
      image = utils.draw_bbox(original_image, pred_bbox)
  
      child.send([img])
      child.close()
  
  if __name__ == &quot;__main__&quot;:
      processes = Queue()
      parent_pipes = Queue() 
      overflow = Queue()
      while True: 
          ret, pic = vid.read()
          overflow.put(pic)
          if processes.qsize() &lt; 4: 
              parent, child = Pipe()
              parent_pipes.put(parent)
              process = Process(target=eval_im, args=(overflow.get(), child))
              processes.put(process)
              process.start()
          print(parent_pipes.qsize())
          if parent_pipes.queue[0].poll(): 
              process = processes.get()
              process.join()
              parent_pipe = parent_pipes.get()
              img = parent_pipe.recv()
              parent_pipe.close()
              
              # cv2.imshow(&quot;frame&quot;, img)
          if cv2.waitKey(1) &amp; 0xFF == ord('q'):
              break 
      vid.release()
      cv2.destroyAllWindows()
  </code></pre>
  <p>Here is the output:</p>
  <pre><code>Traceback (most recent call last):
    File &quot;testing_multi.py&quot;, line 89, in &lt;module&gt;
      img = parent_pipe.recv()
    File &quot;/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/connection.py&quot;, line 250, in recv
      buf = self._recv_bytes()
    File &quot;/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/connection.py&quot;, line 407, in _recv_bytes
      buf = self._recv(4)
    File &quot;/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/connection.py&quot;, line 383, in _recv
      raise EOFError
  EOFError
  </code></pre>