Search code examples
pythonmultiprocessingglobal-variablespython-multiprocessing

Python global var in multiprocessing


For the following code, I declare 'GlobalCount' that is intended to be the global variable. Then I start the process() method with multiprocessing, that increments GlobalCount each second. If I set a breakpoint there, the value is incremented ok. Then, in parallel, I am requesting 'GETSTATUS', who should return the value of GlobalCount. However, it is always 0! What I am doing wrong? Thank you.

Updated code:

import multiprocessing
import socket
import time

from multiprocessing import Value

#globals
GlobalCount = Value('i', 0)  # 'i' stands for integer

def main():

    server_ip = "127.0.0.1"
    server_port = 2222

    # Create a UDP socket
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    server_address = (server_ip, server_port)
    server_socket.bind(server_address)

    response = ""

    print("UDP server is listening on {}:{}".format(*server_address))

    while True:
        
        # Receive data from the client
        data, client_address = server_socket.recvfrom(256)

        if data:

            data_str = data.decode('utf-8') 
            arrayParams = data_str.split(';')

            if arrayParams[0] == "PROCESS":

                server_socket.sendto(response.encode(), client_address)

                # Start the process in parallel
                training_process = multiprocessing.Process(target=process)
                training_process.start()

            elif arrayParams[0] == "GETSTATUS":
                current_value = GlobalCount.value
                response = str(current_value) #here GlobalCount is always 0
                server_socket.sendto(response.encode(), client_address)

            else:
                print("")



def process():

    for i in range(100):
        
        with GlobalCount.get_lock():  # Ensure thread-safety when updating the value
            GlobalCount.value += 1
        time.sleep(1)


#Execute at start
if __name__ == '__main__':
    main()

Solution

  • You can only share synchronised objects through inheritance. Here's an example:

    from multiprocessing import Value, Pool
    
    N = 100
    
    def ipp(v):
        global gCount
        gCount = v
    
    def process(_):
        with gCount.get_lock():
            gCount.value += 1
    
    def main():
        gCount = Value('Q', 0) # unsigned long long
        with Pool(initializer=ipp, initargs=(gCount,)) as pool:
            pool.map(process, range(100))
        print(gCount.value == N)
    
    if __name__ == '__main__':
        main()
    

    Output:

    True