Kev1n91
Kev1n91

Reputation: 3693

When lists are thread safe in python, is it safe to delete them?

I have a multi threaded application in Python 3 and have a setter and getter method of a list. The setter method appends an element to the list, while the getter method deletes all elements of the list after returning them.

The setter method looks like the following, which is in a larger async function:

while self.semaphor:
   print("waiting...")
   time.sleep(0.001)
self.semaphor=True
self.messages.append(msg)
print("appended data!")

While the getter method looks like the following:

while self.semaphor:
    time.sleep(0.001)
self.semaphor = True
l = self.messages
self.messages = []
self.semaphor = False
if len(l) == 0:
   return None
else:
   return l

However the application crashes without any error messages (probably hidden due to multithreaded output in the command line) right after the prinst statetement "append data" - So I was wondering if the code snippets are thread safe and correct?

Upvotes: 0

Views: 1520

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1124238

Your code is not threadsafe, because your self.semaphore handling is not thread-safe. Two threads can read self.semaphore as False, before either of them have set it to True, as thread switches can take place at any point between instructions.

What you want to use is a proper thread lock object (a semaphore is the wrong primitive to use here).

When creating your instance, set a self.messages_lock = threading.Lock() attribute, and whenever you need to alter your messages list, use:

with self.messages_lock:
    # locked block of code, guaranteed to be thread-safe.

or

try:
    while not self.messages_lock.acquire(timeout=0.01):
        print("waiting...")
    # locked block of code, guaranteed to be thread-safe.
finally:
    self.messages_lock.release()

if you must have a thread that prints out that it is waiting for a lock.

Upvotes: 4

Related Questions