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

时间:2015-02-23 08:01:23

标签: python multithreading dictionary

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

在代码中,一个线程(TestAccess)将侦听Web连接并创建对象并更新其变量,为其分配密钥并相应地插入到全局字典(client_list)中。另一个线程(data_cleaner)将遍历此全局字典中的键列表,并检查每个对象中的某些值,如果符合某些条件,则会删除对象。

我创建的对象(clientObject)在创建时会附加另一个对象(deviceObject) - 只是你知道。

当我运行两个线程时,应该检查对象的线程(data_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()

1 个答案:

答案 0 :(得分:1)

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

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()