title: Why are these Python processes stepping on each other?
body: <p>I have a simulation that runs on multiple processes. They get their input (a NumPy array containing just integers - no nested objects or other arrays) from a queue, and often report results through another queue. The parent process does this:</p>
  <p>1 - populates the input queue with a cope of the data for each process:</p>
  <pre><code>        output_queue = multiprocessing.Queue()
          input_queue = multiprocessing.Queue()
  
          for _ in range(parallel_populations):
              new_input = {
                  'data': np.copy(data_source),
              }
              input_queue.put(new_input)
  </code></pre>
  <p>2 - starts each process:</p>
  <pre><code>        processes = []
          for i in range(parallel_populations):
              process = multiprocessing.Process(target=run_population,
                                                args=(
                                                    input_queue,
                                                    output_queue
                                                ))
              process.start()
              processes.append(process)
  </code></pre>
  <p>3 - then, indefinitely, listens to the outputs coming from the output_queue and kills all processes, and restarts them with the new data:</p>
  <pre><code>while True:
      # kill all processes
      result = output_queue.get(True)
      for i in range(len(processes)):
          processes[i].kill()
  
      # populate input_queue again with new data:
      for _ in range(parallel_populations):
          new_input = {
              'data': np.copy(result),
          }
          input_queue.put(new_input)
  
      # finally, start the processes again
      processes = []
      for i in range(parallel_populations):
          process = multiprocessing.Process(target=run_population,
                                            args=(
                                                input_queue,
                                                output_queue
                                            ))
          process.start()
          processes.append(process)
  </code></pre>
  <p>Note that every time I put that data array in the input_queue, I make a np.copy so that each process has its own copy. The processes modify the data.</p>
  <p>If I run only one process at a time, it runs well indefinitely. But if I launch more than one, they corrupt the data in the array as if i had not made copies before putting in the input_queue.</p>
  <p>Doesn't <code>np.copy</code> create a full copy of the ndarray? Since they have just numbers, I thought this was sufficient.</p>
  <p>I also tried using <code>data = data[:]</code> before putting into the queue to make a copy, but same results. Lastly, I tried using <code>copy.deepcopy</code> even though shouldn't be needed. Same results.</p>
  <p>I also tried starting the processes with <code>forkserver</code> as well as <code>spawn</code> to see if memory isolation improved, but same results.</p>
  <p>I can't seem to figure out why are they stepping on each other. I'm on Python 3.8.</p>
  <p>Any pointers are greatly appreciated!</p>