Python中的多线程,以前的数据和实际数据相同

o2g1uqev  于 11个月前  发布在  Python
关注(0)|答案(3)|浏览(85)

我正在实现一个多线程,我有一个问题的数据。基本上(简化代码)第一个线程是收集数据从外部源每0.5秒。代码如下:

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)

字符串
另一个线程检查以前的数据和活动数据是否相同或已更改

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)


我遇到的问题是,在循环期间,dataRefPrevious总是与dataRefActive相同,为什么?

inkz8wg9

inkz8wg91#

Q:eventCheck函数在发布data_lock后会做什么?

当线程A解锁并立即重新锁定一个互斥锁,而另一个线程B正在等待它时,很可能A每次都是赢家,而B永远不会有机会。这并不“公平”,但在大多数操作系统中,互斥锁通常是这样实现的。
我不确定这是不是你的程序中发生的事情(顺便说一下,它被称为“饥饿”),但是如果你想让readData函数有机会绕着它的循环一圈,时不时地收集一些数据,那么你可以尝试让另一个线程时不时地释放互斥量一段时间。
也许只需要将sleep(1)调用增加四个空格就可以了?按照编写的方式,sleep(1)是不可访问的代码。

k3bvogb1

k3bvogb12#

检查缩进,sleep(1)应该在while循环内:

import threading
from random import random
from time import sleep

dataRef = {}
data_lock = threading.Lock()

def simulate_external_data_source():
    return {"some_data": random()}

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

def eventCheck():
    global dataRef
    dataRefPrevious = {}
    dataRefActive = {}

    while True:
        with data_lock:
            if dataRefPrevious:
                dataRefActive = dataRef
                print(
                    "dataRefPrevious", dataRefPrevious, "dataRefActive", dataRefActive
                )
                dataRefPrevious = dataRefActive
            else:
                dataRefPrevious = dataRef
        sleep(1)

if __name__ == "__main__":
    thread1 = threading.Thread(target=readData)
    thread2 = threading.Thread(target=eventCheck)

    thread1.start()
    thread2.start()

    thread1.join()
    thread2.join()

字符串
印刷品:

dataRefPrevious {'some_data': 0.5985874620376193} dataRefActive {'some_data': 0.7163935517084643}
dataRefPrevious {'some_data': 0.7163935517084643} dataRefActive {'some_data': 0.22781975365213092}
dataRefPrevious {'some_data': 0.22781975365213092} dataRefActive {'some_data': 0.6816334934944924}
dataRefPrevious {'some_data': 0.6816334934944924} dataRefActive {'some_data': 0.4299086235625371}
dataRefPrevious {'some_data': 0.4299086235625371} dataRefActive {'some_data': 0.568689886521501}
dataRefPrevious {'some_data': 0.568689886521501} dataRefActive {'some_data': 0.8662567855976215}

...

ctehm74n

ctehm74n3#

我可能发现了一个问题,但没有明确的解释为什么...
我测试了一个函数:

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)

字符串
我得到的是:

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}

然而,当我在代码中替换以下行时:

dataRefPrevious = dataRefActive


收件人:

dataRefPrevious.update(dataRefActive)


我得到正确的价值观如下(以前不同,比活跃)

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}

我认为=将dict dataRefPrevious的ref设置为dataRefActive dict,而.update()更改了变量本身。

相关问题