Search code examples
python-3.xmultithreadinggarbage-collectiondel

Attempting to delete global objects from list using threads, del function not working


I am programming a server in python and attempting to delete a list of globally cached objects with a different thread than the one that originaly stored the objects in the list. When I call del it does not actually delete the objects and after checking the reference count it returns 2032 references.

I am calling the del function once the program is shutdown and it works correctly. However, when attempting to do it mid run it does not seem to work (presumably because of the 2032 references it has). I am wondering if I am attempting to delete from the list wrong or if there is a better way to delete/store the cached objects.

Here is my maintain cache function that is running on my second thread. The number of cached chats and users stays the same before and after the delete.

# maintains the server cache, deleting and refreshing objects as needed
def maintainCache():
    global serverRunning
    start = time.monotonic()
    while (serverRunning):
        time.sleep(30.0 - ((time.monotonic() - start) % 30.0))
        print("Deleting cache...")
        print(f"Active chats: {getNumberOfCachedChats()}")
        print(f"Active users: {getNumberOfCachedUsers()}")
        deleteCachedUserObjects()
        deleteCachedChats()
        print(f"Active chats: {getNumberOfCachedChats()}")
        print(f"Active users: {getNumberOfCachedUsers()}")

Both of the deleteCached functions are identical. Here is one of them. I did try specifying global before running the for loop but that did not seem to change anything.

def deleteCachedUserObjects():
    for user in userList:
        del user

Solution

  • del isn't a function. It's a keyword, and the operand, user, in the statement, del user is an l-value. user is the name of a place that contains a reference to an object, and del user doesn't operate on the object, it operates on the place.

    In your program, user is a local variable, and del user literally destroys the local variable. It has no effect on the object to which the variable referred, and it has no effect on userList which also happens to contain a reference to the same object.

    userList[i] also would name a place if i held a reference to an integer value, and
    del userList[i] would operate on that place by deleting the ith element, making the list shorter by one element. So if you want to make the list empty, you could do this:

        while len(userList) > 0:
            del userList[0]
    

    But, wait! There's a simpler way. You can do the same thing with the clear function. You can make the userList become empty with a single function call:

        userList.clear()