0

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.

Ishraq
  • 11
  • 5
  • You have edited your question to correct the error yet made no indication that you have done so. People will come along and look at this and now wonder why you are getting no output from a correct program. – Booboo Feb 09 '21 at 13:11
  • I didn't correct the error. ( just i had a mistake when i was writing the code here in stackoverflow and inside of writing if ` __name__` and i wrote _name_and it was not this my question. If it is this the case, i should got a NameError: name 'name' is not defined) But my question is: despite the code is correct I have always the same problem which is the multiprocessing is not working in my case and i have no output. Thank you for your undrestanding – Ishraq Feb 09 '21 at 13:29
  • It's good that you clarified this. There have already been answers based on your typo. See my answer below. – Booboo Feb 09 '21 at 13:41

3 Answers3

1

It might be a typo in if _name_ == '__main__': missing an underscore.

Running:

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()

on my machine returns the correct output

Nidal Barada
  • 373
  • 2
  • 14
  • sorry it was not this the problem it was only a mistake when i write the code here. Despite i wrote it correctly but i had no result – Ishraq Feb 09 '21 at 12:48
  • try to set i in range(150) and check your cpu activity in task manger to check whether the processes are actually being created. – Nidal Barada Feb 09 '21 at 12:55
  • yes when i checked my cpu activity in task manager i observed that the processes were being created but i got no result in spyder or also in jupyter – Ishraq Feb 09 '21 at 13:25
0

You need to force flush otherwise the output will only be visible if the buffer becomes full:

def proc(i):
    print(f'I am Process {i}')
    sys.stdout.flush()

PS: You also have a typo when checking for for __name__. It should be if __name__ == '__main__':

Giorgos Myrianthous
  • 36,235
  • 20
  • 134
  • 156
0

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())
Booboo
  • 38,656
  • 3
  • 37
  • 60
  • thank you for your response. Yes there is nothing under the cell but plz how i can access to the notebook console – Ishraq Feb 09 '21 at 15:03
  • Why do you have to run this under Notebook? Can't you just run this (or your original code) from a Windows/Linux command prompt?. But if you *must* run under Notebook, I have updated my answer. – Booboo Feb 09 '21 at 15:20
  • okay thank you this works with me :D if its possible i want to undrestand the cause because i will try to implement the solution in spyder and also it was the same problem here – Ishraq Feb 09 '21 at 15:43
  • Honestly, I don't know why Notebook works that way. My guess is that it captures output written to stdout and then writes it under the cell. But it does this only for the process that is running in the cell, not for any subprocesses that it creates. You should read up on multiprocessing pooling. There are two classes that comes with Python for doing this, class `Pool` in module `multiprocessing` and class `ProcessPoolExecutor` in module `concurrent.futures`. I will add an example using `ProcessPoolExecutor`. – Booboo Feb 09 '21 at 16:05