2

I'm new into multiprocessing in Python (2.7).

I try to run the following piece of code:

from time import sleep
from multiprocessing import Process
import multiprocessing

def func(x):
    print("start %s"%(x))
    sleep(x)
    print("end %s"%(x))
    return

if __name__ == '__main__':

    Process(target=func(10)).start()
    Process(target=func(1)).start()

This return something as :

start 10
end 10
start 1
end 1

While start 1 and end 1 should a priori appear before end 10.

I would appreciate help to understand what I might be missing here.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
Bob
  • 43
  • 1
  • 1
  • 3

3 Answers3

8

You write:

Process(target=func(10)).start()

This means that the Process never is given func, it is given the result of func(10) since Python first evaluates the arguments left-to-right, and then passes the result of these evaluations to the outer function (here the Process(..) call).

In order to let the subprocess evaluate the function, you should write it like:

Process(target=func,args=(10,)).start()

Now you pass a reference to the func function, and you provide a tuple of arguments args with which the sub process is going to call the function. The subprocess will then call func(10) itself (and another subprocess will almost concurrently do the same with func(1)).

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • 1
    You were faster than me ;) When something is working as we don't expect, I recommend to print as mutch as we can, it helps you a lot to understand the way it works. – Víctor López Jul 21 '17 at 12:15
  • 1
    Shame on me. Thanks a lot for your help. – Bob Jul 21 '17 at 13:06
  • 1
    It is surprisingly easy to miss this when you have arguments no matter how good you understand the difference between referencing and running the function – astackoverflowuser Apr 13 '21 at 21:50
1

When creating a Process, target should be function name only without arguments or parantheses and then you add args=(your args). For example:

Process(target=func, args=(10,)).start()
Mohd
  • 5,523
  • 7
  • 19
  • 30
1

Using Willem Van Onsem answer:

from time import sleep
from multiprocessing import Process
import multiprocessing

def func(x, called_from):
    print("start %s from %s"%(x, called_from))
    sleep(x)
    print("end %s from %s"%(x, called_from))
    return

if __name__ == '__main__':

    Process(target=func, args=(10,'1')).start()
    Process(target=func, args=(1,'2')).start()

You can use a lot of Process more to see when they're called and when they finish. Use other Process calls to see how they work.

Víctor López
  • 819
  • 1
  • 7
  • 19