pythonmultithreadingdictionarypython-3.11

Multithreading in Python , previous and actual data in dictionary are the same


I'm implementing a multithreading in Python and I have an issue with the data. Basically (simplifying the code)first thread is collecting data from external source each 0.5s. The code is as follow:

dataRef = {}
data_lock = threading.Lock()

def readData():
  global dataRef
  dataRefNew = {}
  while True:
      dataRefsValues = simulate_external_data_source()
      with data_lock:
         dataRef = dataRefsValues
      sleep(0.5)

And another thread which checks if previous data and active data are the same or changed

def eventCheck():
    global dataRef
    dataRefPrevious = {}
    dataRefActive = {}
    
    while True:
        with data_lock:
            if bool(dataRefPrevious) == True:
                dataRefActive = dataRef
                print('dataRefPrevious', dataRefPrevious,"\n")
                print('dataRefActive', dataRefActive, "\n")
                dataRefPrevious = dataRefActive
            else:
                dataRefPrevious = dataRef
    sleep(1)

The problem I got is that during the looping dataRefPrevious is always the same as dataRefActive, why?


Solution

  • I potentially found a issue but have not a clear explanation why...

    I tested a function:

    def eventCheck():
       global dataRef
       dataRefPrevious = {}
       dataRefActive = {}
       i = 0
       while True:
            i +=1  
            print("\n Iteration: ", i)
            with data_lock:
                dataRefActive = dataRef
                print('dataRefActive  : ', dataRefActive)
                print('dataRefPrevious: ', dataRefPrevious)
    
            if dataRefPrevious:
                print('dataRefPrevious in if statment: ', dataRefPrevious)
                dataRefPrevious = dataRefActive
            else:
                dataRefPrevious = dataRefActive
            sleep(1)
    

    And what I get is:

     Iteration:  1
    dataRefActive  :  {'flaps': 0.0}
    dataRefPrevious:  {}
    
     Iteration:  2
    dataRefActive  :  {'flaps': 0.0}
    dataRefPrevious:  {'flaps': 0.0}
    dataRefPrevious in if statment:  {'flaps': 0.0}
    
     Iteration:  3
    dataRefActive  :  {'flaps': 1.2505772113800049}
    dataRefPrevious:  {'flaps': 1.2505772113800049}
    dataRefPrevious in if statment:  {'flaps': 1.2505772113800049}
    
     Iteration:  4
    dataRefActive  :  {'flaps': 4.265423774719238}
    dataRefPrevious:  {'flaps': 4.265423774719238}
    dataRefPrevious in if statment:  {'flaps': 4.265423774719238}
    
     Iteration:  5
    dataRefActive  :  {'flaps': 7.3065643310546875}
    dataRefPrevious:  {'flaps': 7.3065643310546875}
    dataRefPrevious in if statment:  {'flaps': 7.3065643310546875}
    

    However when I repalce the the following line in the code:

    dataRefPrevious = dataRefActive
    

    to:

    dataRefPrevious.update(dataRefActive)
    

    I'm getting correct values as follow (previous different than active)

    Iteration:  1
    dataRefActive  :  {'flaps': 0.0}
    dataRefPrevious:  {}
    
     Iteration:  2
    dataRefActive  :  {'flaps': 0.0}
    dataRefPrevious:  {'flaps': 0.0}
    dataRefPrevious in if statment:  {'flaps': 0.0}
    
     Iteration:  3
    dataRefActive  :  {'flaps': 0.20687073469161987}
    dataRefPrevious:  {'flaps': 0.0}
    dataRefPrevious in if statment:  {'flaps': 0.0}
    
     Iteration:  4
    dataRefActive  :  {'flaps': 3.2361574172973633}
    dataRefPrevious:  {'flaps': 0.20687073469161987}
    dataRefPrevious in if statment:  {'flaps': 0.20687073469161987}
    
     Iteration:  5
    dataRefActive  :  {'flaps': 6.276290416717529}
    dataRefPrevious:  {'flaps': 3.2361574172973633}
    dataRefPrevious in if statment:  {'flaps': 3.2361574172973633}
    
     Iteration:  6
    dataRefActive  :  {'flaps': 9.321335792541504}
    dataRefPrevious:  {'flaps': 6.276290416717529}
    dataRefPrevious in if statment:  {'flaps': 6.276290416717529}
    

    I'm thinking that = makes a ref of dict dataRefPrevious to dataRefActive dict while .update() changes the variable itself.