Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python block thread if list is empty

Tags:

Is there a way to make a thread go to sleep if the list is empty and wake it up again when there are items? I don't want to use Queues since I want to be able to index into the datastructure.

like image 999
mrQWERTY Avatar asked Jul 27 '16 20:07

mrQWERTY


People also ask

How do you check if a list is empty in Python?

Empty lists are considered False in Python, hence the bool() function would return False if the list was passed as an argument. Other methods you can use to check if a list is empty are placing it inside an if statement, using the len() methods, or comparing it with an empty list.

How do you check if a thread is done Python?

Once the thread's activity is started, the thread is considered 'alive'. It stops being alive when its run() method terminates – either normally, or by raising an unhandled exception. The is_alive() method tests whether the thread is alive.

How do you stop a blocked thread?

Launch a seperate thread to perform the blocking call, and terminate() it if you need to stop the thread. You can use the IOU mechanism of Threads.


2 Answers

Yes, the solution will probably involve a threading.Condition variable as you note in comments.

Without more information or a code snippet, it's difficult to know what API suits your needs. How are you producing new elements? How are you consuming them? At base, you could do something like this:

cv = threading.Condition()
elements = []  # elements is protected by, and signaled by, cv

def produce(...):
  with cv:
    ... add elements somehow ...
    cv.notify_all()

def consume(...):
  with cv:
    while len(elements) == 0:
      cv.wait()
    ... remove elements somehow ...
like image 111
pilcrow Avatar answered Sep 28 '22 03:09

pilcrow


I would go with this:

import threading

class MyList (list):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._cond = threading.Condition()

    def append(self, item):
        with self._cond:
            super().append(item)
            self._cond.notify_all()

    def pop_or_sleep(self):
        with self._cond:
            while not len(self):
                self._cond.wait()
            return self.pop()
like image 30
Messa Avatar answered Sep 28 '22 01:09

Messa