shamax
shamax

Reputation: 21

Accessing Global Dictionary via two separate threads return different results

I'm having trouble when trying to access a global dictionary which holds objects as values.

Within the code, one thread (TestAccess) will listen to web connections and create objects and update its variables, assign a key to it and insert in to the global dictionary (client_list) accordingly. While the other thread (data_cleaner) will go through the list of keys in this global dictionary and check for certain values in each object and will delete objects if it meets certain criteria.

The objects I'm creating (clientObject) attaches another object (deviceObject) when it gets created - just so you know.

When I run both threads, the thread that should check objects (data_cleaner) will not see the dictionary being updated. It always returns {}. If I run the functions without any treads and both returns the correct dictionary values as expected.

I have tried the global keyword but had no luck. Also added a Lock() just to make sure we don't have any simultaneous resource access issues.

Can someone please shed some light on this? Following is the structure of my code.

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

Upvotes: 1

Views: 213

Answers (1)

shamax
shamax

Reputation: 21

With MartijnPieters help I was able to resolve this issue by adding the "autoreloader = False" as a parameter when creating the web object as shown below.

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

Upvotes: 1

Related Questions