0

I am trying to gain an insight into using multiprocessing with python. I have an example of using shared values for Unix but I cannot get a simple educational example to work on Windows 10. I have the code below running ok on Windows but with the call updating the shared value commented out in foo(). What is my problem please?

import multiprocessing as mp

def foo(q):
    #global shared_num
    q.put('hello')
    #shared_num.value = 777

if __name__ == '__main__':
    global shared_num
    mp.set_start_method('spawn')
    shared_num = mp.Value('d', 0)
    lock = mp.Lock()
    q = mp.Queue()
    p = mp.Process(target=foo, args=(q,))
    p.start()
    p.join()
    print(q.get(), " ",shared_num.value)
    #print(q.get(), " ")

If I run the code below with the foo() setting the shared value I get:

Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.2032.0_x64__qbz5n2kfra8p0\lib\multiprocessing\process.py", line 315, in _bootstrap
    self.run()
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.2032.0_x64__qbz5n2kfra8p0\lib\multiprocessing\process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\ken38\OneDrive\Projects\Python\GH_Pi\python\ms_mp.py", line 6, in foo
    shared_num.value = 777
NameError: name 'shared_num' is not defined
hello   0.0
IInspectable
  • 46,945
  • 8
  • 85
  • 181
ken205726
  • 21
  • 5
  • On Windows (or if start method is explicitly "spawn") the subprocess is generated by executing the whole module except the main-guard and then calling the designated function. This means that "shared_num" is never set in the subprocess. Solution: Add it as argument to the "foo" call. – Michael Butscher Feb 11 '21 at 14:12
  • The same is required with the lock. The code now works on Windows 10 and Debian. I will try and build a more complicated example. Thankyou. – ken205726 Feb 11 '21 at 15:26
  • Don't edit the answer into the question. If you have an answer and want to share it, submit an answer. – IInspectable Feb 11 '21 at 17:12
  • Pretty unhappy with the tone of that response but perhaps it did not mean to be impolite to a very rare user of forum's for that very reason. – ken205726 Feb 11 '21 at 18:25
  • 1
    Could be a direct result of the fact that you ignored to inform yourself about how this site works. Why did you *actively* decide against taking the [tour], for example? The result: I had to invest time into cleaning up after you as a result of you trying to save time. Maybe that explains why the response is no more friendly than absolutely required. – IInspectable Feb 12 '21 at 10:04
  • If you had pointed out my error I would have copied and pasted my "edit" into an Answer but at the time I could not see that link and wanted to record it while I had it to hand. Instead it is lost forever and the next Newbie will fail to find a flagged answer. – ken205726 Feb 13 '21 at 11:19
  • What do you mean by "it is lost forever", click the "edited" link below your question and find the previous versions. All still there, ready for the copy pasting. – Yunnosch Feb 13 '21 at 11:26

1 Answers1

0

Michael Butscher actually answered this with his comment. But as I could not flag that as an answer I thought I would show the corrected code as an answer. This does highlight difference if you try and test simple examples on Windows. Linux based examples may not work an Windows. This code worked on both Windows and Debian (Rpi).

import multiprocessing as mp

def foo(q, shared_num, lock):
    #global shared_num
    q.put('hello')
    with lock:
        shared_num.value = 777

if __name__ == '__main__':
    global shared_num
    mp.set_start_method('spawn')
    shared_num = mp.Value('d', 0)
    lock = mp.Lock()
    q = mp.Queue()
    p = mp.Process(target=foo, args=(q, shared_num, lock,))
    p.start()
    p.join()
    print(q.get(), " ",shared_num.value)
    #print(q.get(), " ")
ken205726
  • 21
  • 5