title: Difference between apply() and apply_async() in Python multiprocessing module
body: <p>I currently have a piece of code which spawns multiple processes as follows: </p>
  
  <pre><code>pool = Pool(processes=None)
  results = [pool.apply(f, args=(arg1, arg2, arg3)) for arg3 in arg_list]
  </code></pre>
  
  <p>My idea was that this would divide the work across cores, using all cores available since <code>processes=None</code>. However, the documentation for the <code>Pool.apply()</code> method in the <a href="https://docs.python.org/2/library/multiprocessing.html#module-multiprocessing.pool" rel="noreferrer">multiprocessing module docs</a> reads:</p>
  
  <blockquote>
    <p>Equivalent of the apply() built-in function. It blocks until the result is ready, so apply_async() is better suited for performing work in parallel. Additionally, func is only executed in one of the workers of the pool.</p>
  </blockquote>
  
  <p><strong>First question:</strong>
  I don't clearly understand this. How does <code>apply</code> distribute the work across workers, and in what way is it different from what <code>apply_async</code> does? If the tasks get distributed across workers, how is it possible that <code>func</code> is only executed in one of the workers? </p>
  
  <p><strong>My guess</strong>: my guess would be that the <code>apply</code>, in my current implementation, is giving a task to a worker with a certain set of arguments, then waiting for that worker to be done, and then giving the next set of arguments to another worker. In this way I am sending work to different processes, yet <strong>no parallelism is taking place</strong>. This seems to be the case since <code>apply</code> is in fact just:</p>
  
  <pre><code>def apply(self, func, args=(), kwds={}):
      '''
      Equivalent of `func(*args, **kwds)`.
      Pool must be running.
      '''
      return self.apply_async(func, args, kwds).get()
  </code></pre>
  
  <p><strong>Second question:</strong> I would also like to understand better why, in the introduction of the <a href="https://docs.python.org/2/library/multiprocessing.html#introduction" rel="noreferrer">docs</a>, section 16.6.1.5. ('Using a pool of workers'), they say that even a construction with <code>apply_async</code> such as
     <code>[pool.apply_async(os.getpid, ()) for i in range(4)]</code>
  <em>may</em> use more processes, but it isn't sure that it will. <strong>What decides whether multiple processes will be used?</strong></p>