No output from Process using multiprocessing

2019-05-11 13:28发布

问题:

I am a beginner in multiprocessing, can anyone tell me why this does not produce any output?

import multiprocessing

def worker(num):
    """thread worker function"""

    print('Worker:', num)

if __name__ == '__main__':
    jobs = []

    for i in range(4):
        p = multiprocessing.Process(target=worker, args=(i,))
        jobs.append(p)
        p.start()

回答1:

You're starting your Process(), but never waiting on it to complete, so your program's execution ends before the background process finishes. Try this, with a call to Process.join():

import multiprocessing
import sys

def worker(num):
    """thread worker function"""

    print('Worker:', num)
    sys.stdout.flush()

if __name__ == '__main__':
    jobs = []

    for i in range(4):
        p = multiprocessing.Process(target=worker, args=(i,))
        jobs.append(p)
        p.start()

    map(lambda p: p.join(), jobs)

Here we use map() to call join() on each process in the jobs list.

Here's an example of this working:

In [127]: %paste
import multiprocessing
import sys

def worker(num):
    """thread worker function"""

    print('Worker:', num)
    sys.stdout.flush()

if __name__ == '__main__':
    jobs = []

    for i in range(4):
        p = multiprocessing.Process(target=worker, args=(i,))
        jobs.append(p)
        p.start()

    map(lambda p: p.join(), jobs)

## -- End pasted text --
Worker: 2
Worker: 1
Worker: 0
Worker: 3

In [128]:

As for why this isn't working in IDLE, see this answer:

However, to see the print output, at least on Windows, one must start IDLE from a console like so.

C:\Users\Terry>python -m idlelib
hello bob

(Use idlelib.idle on 2.x.) The reason is that IDLE runs user code in a separate process. Currently the connection between the IDLE process and the user code process is via a socket. The fork done by multiprocessing does not duplicate or inherit the socket connection. When IDLE is started via an icon or Explorer (in Windows), there is nowhere for the print output to go. When started from a console with python (rather than pythonw), output goes to the console, as above.



回答2:

You probably need to flush the output. You can use sys.stdout.flush():

import multiprocessing
import sys

def worker(num):
    """thread worker function"""
    print('Worker:', num)
    sys.stdout.flush()
    return

if __name__ == '__main__':
    jobs = []
    for i in range(4):
        p = multiprocessing.Process(target=worker, args=(i,))
        jobs.append(p)
        p.start()