Python 通过两个单独的线程访问全局字典会返回不同的结果

Python 通过两个单独的线程访问全局字典会返回不同的结果,python,multithreading,dictionary,Python,Multithreading,Dictionary,我在尝试访问将对象作为值保存的全局字典时遇到问题 在代码中,一个线程(TestAccess)将侦听web连接,创建对象并更新其变量,为其分配一个键,并相应地插入全局字典(client_list)。而另一个线程(data\u cleaner)将遍历此全局字典中的键列表,检查每个对象中的特定值,并在满足特定条件时删除对象 我正在创建的对象(clientObject)在创建时会附加另一个对象(deviceObject) 当我运行两个线程时,应该检查对象的线程(data\u cleaner)将看不到字典

我在尝试访问将对象作为值保存的全局字典时遇到问题

在代码中,一个线程(
TestAccess
)将侦听web连接,创建对象并更新其变量,为其分配一个键,并相应地插入全局字典(
client_list
)。而另一个线程(
data\u cleaner
)将遍历此全局字典中的键列表,检查每个对象中的特定值,并在满足特定条件时删除对象

我正在创建的对象(
clientObject
)在创建时会附加另一个对象(
deviceObject

当我运行两个线程时,应该检查对象的线程(
data\u cleaner
)将看不到字典正在更新。它总是返回
{}
。如果我在没有任何踏板的情况下运行函数,并且两者都返回正确的字典值

我尝试了
global
关键字,但没有成功。还添加了一个
Lock()
,以确保不会同时出现任何资源访问问题

有人能解释一下吗?下面是我的代码结构

import web
import json
import threading
import time

urls = (
'/testaccess', "TestAccess"
)

client_list = {}
lock = threading.Lock()

class clientObject(object):
    # each created object here will attach another object from from deviceObject  below

class deviceObject(object):
    # Object items

class TestAccess:
    def __init__(self):
       pass

    def GET(self):
        return "abcd"

    def POST(self):
        raw_data = web.data()
        json_dic = json.loads(raw_data)
        process_data(json_dic)


 def process_data (json_dic)
    global lock
    global client_list

    lock.acquire()

    # Perform some processing on the JSON data.

    if XXXXXXXXXXXX:
        # Create the new object and and update values.

        client_list[ID] = clientObject()
        client_list[ID].XX[ID].pred_vals(jsonInfo)
    else:
        # Update the object

    print client_list # This prints all key:value pairs nicely as expected.

    lock.release()

def data_cleaner()
    global lock
    global client_list
    while True:
        lock.acquire()

        print client_list # this prints out just  "{}"

        # Do other things
        lock.release()
        time.sleep(5)

if __name__ == "__main__":

    app = web.application(urls, globals())

    def start_web_server():
        app.run()

    T2 = threading.Thread(target=data_cleaner)
    T1 = threading.Thread(target=start_web_server)

    T1.daemon = False

    T1.start()
    T2.start()

在MartijnPieters的帮助下,我可以通过在创建web对象时添加“autoreloader=False”作为参数来解决此问题,如下所示

if __name__ == "__main__":

    app = web.application(urls, globals(), autoreload=False)

    def start_web_server():
        app.run()

    T2 = threading.Thread(target=data_cleaner)
    T1 = threading.Thread(target=start_web_server)

    T1.daemon = False

    T1.start()
    T2.start()

在这里检查什么是
web
?您是否正在为web服务器运行Flask或其他类似的框架?啊,从您运行的代码判断。该项目使用了线程,因此它已经使用了线程。调查他们是否使用forking来支持代码重新加载。您是否使用
web.reloader
中间件?@MartijnPieters抱歉,我不太确定我是否在不知情的情况下使用web.reloader。但我并没有在代码中的任何地方特别要求“web.reloader”。。如果这是你想要的。我对web.py所做的唯一一件事就是监听TCP端口,每当它看到一个连接时,它就会转储数据以供进一步处理,并一直监听。我最初只在主管道内调用一次。希望这能给你一个线索:)