0

So, the one missing piece to a complex (for me at least) program I made in python is that I have two variables outside of two functions (both of which funcs I run as processes, and the processes execute concurrently as expected), and the issue I have is both Process functions are altering the exterior (global) variables, yet when I try to get one from the other, it does not get the proper value (in fact, the first function does not receive any change when the other function prints it. I made a really simplified version of this issue to help explain:

from multiprocessing import Process
import time
global n 
def func1():
    n = False
    while True:
        print(n)
        time.sleep(1)
def func2():
    n = False
    while True:
        n = True
        time.sleep(1)
Process(target=func1).start()
Process(target=func2).start()

So, as you see, n is not getting changed (at least not in the func1). Even if it were to get changed I believe that as they run concurrently it would reset back, as the process would call and reset the value, and I'm really not sure how to get around this situation. I do understand scope but everything I had read indicated this was the proper way to declare this, I was confused as well, but did so. What am I missing/what syntax am I incorrectly handling? I'm sure this is a simple question, and apologies for it, but could not find on this site or elsewhere and it's driving me nuts.

Michael W
  • 343
  • 2
  • 11
  • 1
    The two processes you created have separate memory spaces and do not affect each other. You need some kind of memory sharing and synchronisation to make the variable shared across processes. – Norrius Jan 23 '18 at 00:02
  • Maybe this will help you. [https://stackoverflow.com/questions/17377426/shared-variable-in-pythons-multiprocessing](https://stackoverflow.com/questions/17377426/shared-variable-in-pythons-multiprocessing) – 전원표 Jan 23 '18 at 00:02
  • @전원표 I had read through that but honestly couldn't see its application to my question or even understand what they were trying to do. Norrius, how can I do that? Every solution I thought of involved creating another global var which would just reset the issue... – Michael W Jan 23 '18 at 00:06
  • 1
    I don't see how it's a duplicate as mine involves passing values between two functions ran as processes. I do honestly try to search all questions on here before I post... – Michael W Jan 23 '18 at 00:07
  • Python is a historic program. Therefore, the function to handle shared variables between processes has already been implemented. It is assumed that the article synchronizes variables between processes through a class called Manager. But I have not experimented with this. – 전원표 Jan 23 '18 at 00:12
  • @Norrius I checked it and I think it could possibly work but everything I found online for the ctypes library has to do with windows. How could I create a boolean in Ctypes? – Michael W Jan 23 '18 at 00:19
  • @MichaelW have you managed to solve your problem? – Norrius Jan 30 '18 at 13:27
  • @Norrius I did not, I ended up running the processes in one thread (not concurrently). – Michael W Mar 11 '18 at 03:12

3 Answers3

0

If you want to change the value of a global variable inside a function you must also explicitly declare that variable as global inside that function because otherwise it is a local variable.

def func1():
    global n
    n = False
    ...
Jānis Š.
  • 532
  • 3
  • 14
  • I tried it both ways. I have done this, and that, and because of the way processes work it sets it to false each time so it never gets to be True. – Michael W Jan 23 '18 at 00:18
0

Maybe this will help you.

import time                                                                                                            
from multiprocessing import Process, Manager, Value                                                                    


manager = Manager()                                                                                                    
n = manager.Value('n', False)                                                                                          


def func1(n):                                                                                                          
    n = False                                                                                                          
    while True:                                                                                                        
        print(n)                                                                                                       
        time.sleep(1)                                                                                                  
def func2(n):                                                                                                          
    n = False                                                                                                          
    while True:                                                                                                        
        n = True                                                                                                       
        print(n)                                                                                                       
        time.sleep(1)                                                                                                  

Process(target=func1, args=(n,)).start()                                                                               
Process(target=func2, args=(n,)).start()
전원표
  • 170
  • 1
  • 11
0

The simplest solution here would be having a Value (which is basically an object in shared memory) in both processes. If you intend to do anything non-atomic with it (you likely do), you also need a Lock to synchronise access to this memory.

You don't need to make anything global.

from multiprocessing import Process, Lock, Value
from ctypes import c_bool
import time

def func1(n, lock):
    while True:
        with lock:
            print(n.value)
        time.sleep(1)

def func2(n, lock):
    while True:
        with lock:
            n.value = True
        time.sleep(1)

n = Value(c_bool, False)
lock = Lock()
Process(target=func1, args=(n, lock)).start() 
Process(target=func2, args=(n, lock)).start()
Norrius
  • 7,558
  • 5
  • 40
  • 49