I am learning how to use the multiprocessing
module in Python and experimenting with my own codes following online tutorials. Here is my code
import multiprocessing as mp
import time
manager = mp.Manager()
def update_array_list(datalist):
for i in range(1,10):
datalist.append(i)
print(f"loading list array with {i} elements : {datalist}")
print("_________________________________________")
time.sleep(2)
def display_array_list(datalist):
while True:
print(f"Items in array {datalist} ")
time.sleep(1)
if __name__ == '__main__':
datalist = manager.list()
datalist.clear()
l1 = mp.Process(target=update_array_list,args=(datalist))
l2 = mp.Process(target=display_array_list,args=(datalist))
l1.start()
l2.start()
l1.join()
l2.join()
My l1
process updates shared list datalist
at two seconds intervals while my l2
process print them at 1-second intervals.
My code does not run, although this is nearly the same as tutorials.
I get the following error.
...............
_check_not_importing_main()
File "C:\Users\pgooneti\Anaconda3\envs\NOUS\lib\multiprocessing\spawn.py", line 136, in _check_not_importing_main
is not going to be frozen to produce an executable.''')
RuntimeError:
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.
This probably means that you are not using fork to start your
child processes and you have forgotten to use the proper idiom
in the main module:
if __name__ == '__main__':
freeze_support()
...
The "freeze_support()" line can be omitted if the program
is not going to be frozen to produce an executable.
What is the error here?
CodePudding user response:
On ms-windows and macOS, multiprocessing
comes with some extra programming guidelines.
Due to the way multiprocessing
has to work on those platforms, your script has to be safely importable.
That means that outside the if __name__ == "__main__":
block, you should ideally only have imports, function and class definitions.
And you should certainly not try to instantiate any of the multiprocessing.Process
, multiprocessing.Pool
, multiprocessing.Manager
classes outside of that block!
Consider what happens when you create a Process
outside of the "__main__"
block:
- You start up Python that runs your script.
- You start a
Process
- Python starts a new Python interpreter, which imports your script.
- Which returns you to step 2.
Unchecked, this would fill your machine's memory up with Python processes. Hence the RuntimeError
.
CodePudding user response:
Your code is Ok, just be aware of documentation because the args shoul be a tuple and not a list()
Try chage this lines (Note the comma after the argument):
l1 = mp.Process(target=update_array_list,args=(datalist,))
l2 = mp.Process(target=display_array_list,args=(datalist,))
$ python3 multi.py
loading list array with 1 elements : [1]
_________________________________________
Items in array [1]
Items in array [1]
Items in array [1, 2]
loading list array with 2 elements : [1, 2]
_________________________________________
Items in array [1, 2]
Items in array [1, 2, 3]
loading list array with 3 elements : [1, 2, 3]
_________________________________________
Items in array [1, 2, 3]
Items in array [1, 2, 3, 4]
loading list array with 4 elements : [1, 2, 3, 4]
_________________________________________
Items in array [1, 2, 3, 4]
Items in array [1, 2, 3, 4]
loading list array with 5 elements : [1, 2, 3, 4, 5]
_________________________________________