Search code examples
pythonmultiprocessingpython-multiprocessing

[multiprocessing python]: no output


can someone explain me please why when i tried to execute this below exemple, i have no result. Also i tried to redirect the output in a file but in vain.

from multiprocessing import Process
def proc(i):
    print(f'I am Process {i}')
if __name__ ==  '__main__':
    for i in range(10):
        Process(target=proc, args=(i,)).start()

Normally, i have as output:

I am Process 6
I am Process 2
I am Process 0
I am Process 3
I am Process 7
I am Process 4
I am Process 8
I am Process 1
I am Process 5
I am Process 9

But in my case, i have no result.


Solution

  • If you have to run under Notebook (and have moved your worker function to an external module as required) and you want to see the printout within Notebook, you need to arrange for the printing to be done by the main (launching) process. That means the launched processes need to return the strings to be printed back to the launching process. There are several ways to do that. Here I am using a multiprocessing pool with a callback function so that as soon as a result is ready, the main process is called back with the result:

    from multiprocessing import Pool
    from workers import proc
    
    def on_completion(result):
        print(result)
    
    if __name__ ==  '__main__':
        pool = Pool(10)
        results = [pool.apply_async(proc, args=(i,), callback=on_completion) for i in range(10)]
        pool.close()
        pool.join() # wait for worker processes to exit
    

    A second and simpler way:

    from multiprocessing import Pool
    from workers import proc
    
    
    if __name__ ==  '__main__':
        pool = Pool(10)
        results = pool.imap_unordered(proc, range(10))
        # print the results as they become available:
        for result in results:
            print(result)
    

    Using ProcessPoolExecutor:

    from concurrent.futures import ProcessPoolExecutor, as_completed
    from workers import proc
    
    
    if __name__ ==  '__main__':
        with ProcessPoolExecutor(max_workers=10) as executor:
            futures = [executor.submit(proc, i) for i in range(10)]
            for f in as_completed(futures):
                print(f.result())