Why my subprocess generated by pool.apply_async() always run as MainProcess?
<p>My env is Python2.7.I am very fuzzed,I run my apply_async(test_func),and I let the test_func print the current process_name.As like:</p>

<pre><code>q = Queue(maxsize=20) #multiprocessing.Queue

def test_func(queue):
    print 'Process'
    print multiprocessing.current_process()

if __name__ == '__main__':
    pool = Pool(processes=3)
    for i in xrange(3):
        pool.apply_async(test_func(q,))
    while True:
        time.sleep(1)
        if q.empty():
            break
        print 'Main Process Monitoring'
        print multiprocessing.current_process()
</code></pre>

<p>The code has no syntax error,and the terminal always print <code>&lt;MainProcess&gt;</code> </p>

<p>If I change <code>pool.apply_async(test_func,(q,))(add a comma)</code>,it couldn't get into the <code>test_func</code>,just like simply finish for loop,and it just print <code>'Main Process Monitoring' &lt;MainProcess&gt;</code>..</p>

<p>So I can't understand why <code>apply_async()</code> can't work normally and when it work,it runs as <code>MainProcess</code>,and I have tried <code>pool.close(),pool.join()</code>.Nothing change.
If anyone can help.Thanks a lot!</p>

<p>First, your <code>test_func</code> function has no <code>return</code> statement, so it returns <code>None</code>:</p>

<pre><code>def test_func(queue):
    print 'Process'
    print multiprocessing.current_process()
</code></pre>

<p>Inserting this into an interactive Python:</p>

<pre><code>&gt;&gt;&gt; import multiprocessing
&gt;&gt;&gt; x = test_func(None)
Process
&lt;_MainProcess(MainProcess, started)&gt;
&gt;&gt;&gt; print x
None
</code></pre>

<p>This means that:</p>

<pre><code>    pool.apply_async(test_func(q,))
</code></pre>

<p>calls <code>test_func</code> with argument <code>(q,)</code>, which returns <code>None</code>; then you pass <code>None</code> to <code>pool.apply_async</code>.</p>

<p><a href="https://docs.python.org/2/library/multiprocessing.html" rel="nofollow">The <code>multiprocessing</code> documentation</a> describes <code>apply_async</code> as invoking its first argument a la <code>apply</code>, but asynchronously, i.e., without waiting for its result.  Let's try <code>apply(None)</code> interactively, just to see what that does:</p>

<pre><code>&gt;&gt;&gt; apply(none)
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
TypeError: 'NoneType' object is not callable
</code></pre>

<p>So we might expect <code>apply_async</code> to raise a TypeErrorâand in fact, that <em>is</em> what it does, but the error is deferred until we try to get the result:</p>

<pre><code>&gt;&gt;&gt; pool = multiprocessing.Pool(processes=3)
&gt;&gt;&gt; pool.apply_async(None)
&lt;multiprocessing.pool.ApplyResult object at 0x801b27510&gt;
</code></pre>

<p>Let's grab this ApplyResult object so we can use and inspect it (the special name <code>_</code> holds the most recent value returned during the interaction):</p>

<pre><code>&gt;&gt;&gt; x = _
</code></pre>

<p>Now we can see if the asynchronous apply has a result for us:</p>

<pre><code>&gt;&gt;&gt; x.ready()
True
</code></pre>

<p>It does!  (We can call <code>x.wait()</code> to wait for it if not, but since it's ready now, let's press on.)  Is the result a regular value, or an exception?</p>

<pre><code>&gt;&gt;&gt; x.successful()
False
</code></pre>

<p>Ah, the result is an exception.  Let's get the exception:</p>

<pre><code>&gt;&gt;&gt; x.get()
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  File "/usr/local/lib/python2.7/multiprocessing/pool.py", line 567, in get
    raise self._value
TypeError: 'NoneType' object is not callable
</code></pre>

<p>And there we have the answer: passing <code>None</code> to <code>apply_async</code> spins off the execution of the function <code>None</code> (which is not a function after all), and once we collect the final result, that result is the exception we would expect.</p>

<blockquote>
  <p>If I change <code>pool.apply_async(test_func,(q,))</code> (add a comma), it couldn't get into the <code>test_func</code> ...</p>
</blockquote>

<p>Let's try something like that in the interactive interpreter.  I don't have a <code>q</code> but since <code>test_func</code> does not actually use its arguments, we're OK here with passing None:</p>

<pre><code>&gt;&gt;&gt; x = pool.apply_async(test_func, (None,))
&gt;&gt;&gt; Process
&lt;Process(PoolWorker-2, started daemon)&gt;
</code></pre>

<p>This output is a bit messy but it sure looks like it worked.  Let's see if <code>x</code> has a result, and whether it's successful, and what its result is:</p>

<pre><code>x.ready()
True
&gt;&gt;&gt; x.successful()
True
&gt;&gt;&gt; x.get()
&gt;&gt;&gt;
</code></pre>

<p>(the first <code>&gt;&gt;&gt;</code> prompt seems to be missing, but it's really just been printed-over by the things printed in <code>test_func</code>).  There is a successful value, but since it's None, the interpreter did not print anything hereâwe'd have to have done <code>print x.get()</code> to see it.</p>

<p>In other words, if you're going to use <code>apply_async</code> you must (1) save the spun-off "pending result" somewhere, and then (2) use <code>.get()</code> to actually <em>retrieve</em> that result.  You also need to return something from your function.</p>

<p>Meanwhile this loop:</p>

<pre><code>while True:
    time.sleep(1)
    if q.empty():
        break
    print 'Main Process Monitoring'
    print multiprocessing.current_process()
</code></pre>

<p>never runs all the way through once, because your queue object <code>q</code> <em>is</em> empty at the time you test it, so you immediately <code>break</code> out of it.</p>

python