4

I'm using spyder 5.1.5 and I am trying to follow along with the very first example on a website. I'm getting the error:

AttributeError: Can't get attribute 'task' on <module '__main__' (built-in)>

task is a function that I define.

Full example code:

import multiprocessing
import time

def task(num):
    print("a",num)
    time.sleep(2)
if __name__ == '__main__':  
    for i in range(10):
       p = multiprocessing.Process(target=task,args=(i,))
       p.start()
Chris
  • 18,724
  • 6
  • 46
  • 80
Raiey
  • 51
  • 1
  • 2
  • 1
    In general, multiprocessing doesn't work in browsers or web sites. There has to be a file containing `task` that's in the same file of the multiprocessing statement. Your code above works perfectly when copied to a file – Frank Yellin Mar 07 '22 at 03:34
  • 1
    If you are running in an environment such as Jupyter Notebook or iPython, then you must put function `task` in a separate file, e.g. *task.py*, and then import the function, e.g. `from task import task`. – Booboo Mar 07 '22 at 11:28
  • 1
    Go into spyder settings, and under the "Run" menu: select "Execute in an external system terminal". Then after saving the file, execute it by pressing F5 or by using the "Run File" button. Don't run individual cells or selections of code. – Aaron Mar 07 '22 at 17:33
  • 1
    Also you it would probably be a good idea to wait in the main process for the children to finish. As it stands it "should" work because python attempts to cleanup any existing children by `join`ing them before shutdown, but it's not a good idea to rely on auto-cleanup. You should always explicitly cleanup after resources like open files, running threads, child processes, etc. – Aaron Mar 07 '22 at 17:39
  • @DanielWalker Did Booboo's suggestion not work for you? – aaron Mar 13 '22 at 09:35

1 Answers1

2

As per Python's documentation:

Note: Functionality within this package requires that the __main__ module be importable by the children. This is covered in Programming guidelines, however, it is worth pointing out here. This means that some examples, such as the multiprocessing.pool.Pool examples will not work in the interactive interpreter.

Spyder uses IPython console, allowing you to execute commands and interact with data inside IPython interpreters. However, as mentioned here by a Spyder maintainer: "Multiprocessing doesn't work well on Windows in Spyder's IPython console."

Option 1

Update your Spyder software, as you are using an old - 5.1.5 as you mentioned - version. However, as stated here, "since our 5.2.0 version (released in November 2021), prints generated while running multiprocessing code are captured and displayed in the IPython console for all operating systems".

Option 2

Change the console settings to run your code using an external terminal instead. To do that, please go to: Run > Configuration per file... > Execute in an external system terminal (under console).

Option 3

As described here, you could write your function into a separate file and import it into your script. For instance:

tasks.py

import time

def task(num):
    print("a",num)
    time.sleep(2)

main.py

import multiprocessing
from tasks import task

if __name__ == '__main__':  
    for i in range(10):
       p = multiprocessing.Process(target=task,args=(i,))
       p.start()
Chris
  • 18,724
  • 6
  • 46
  • 80