Оказывает ли многопоточная поддержка очереди перегруженность, даже если используется только для одного потока? - PullRequest
2 голосов
/ 19 января 2012

Многопоточность обычно означает блокировку критических секций и т. Д. Поэтому я не могу не задаться вопросом, в однопоточной программе или многопоточной программе, но где очередь просто используется в одном конкретном потоке, есть ли некоторые(ненужный) тип блокировки служебных данных?

Например, когда вы вызываете put или get или qsize и т. д., блокируется ли он, затем выполняет некоторую обработку, а затем снимает блокировку?

Ответы [ 4 ]

3 голосов
/ 19 января 2012

Queue.Queue реализует блокировку вокруг collections.deque. Если Queue.Queue предполагается использовать только в одном потоке, вы можете заменить его на collections.deque.

1 голос
/ 19 января 2012

Замки жестко закодированы в классе Queue. Таким образом, методы put, get будут использовать блокировки независимо от того, сколько потоков существует в вашей программе. Очередь - это модуль, используемый для облегчения связи между потоками.

Проверка Queue.py реализация

class Queue:
    def __init__(self, maxsize=0):
        ...
        self.mutex = threading.Lock()
        self.not_empty = threading.Condition(self.mutex)
        self.not_full = threading.Condition(self.mutex)
        self.all_tasks_done = threading.Condition(self.mutex)
        self.unfinished_tasks = 0

И его put метод:

def put(self, item, block=True, timeout=None):
    ...
    self.not_full.acquire()
    try:
        if self.maxsize > 0:
            ...
            elif timeout is None:
                while self._qsize() == self.maxsize:
                    self.not_full.wait()
        self._put(item)
        self.unfinished_tasks += 1
        self.not_empty.notify()
    finally:
        self.not_full.release()

Надеюсь, это ответит на ваш вопрос.

UPDATE

Даже метод qsize использует блокировки:

def qsize(self):
    """Return the approximate size of the queue (not reliable!)."""
    self.mutex.acquire()
    n = self._qsize()
    self.mutex.release()
    return n

К вашему сведению, я проверил реализацию Queue.py для Python2.7

1 голос
/ 19 января 2012

Получение и снятие неконтролируемой блокировки чрезвычайно дешево на большинстве современных аппаратных средств.Это одна из первых вещей, которую оптимизируют разработчики аппаратного обеспечения, потому что подавляющее большинство операций блокировок выполняется с помощью необоснованных блокировок.

1 голос
/ 19 января 2012

Да - не обойтись, что будут некоторые накладные расходы.Очередь не может знать, что она будет использоваться только в одном потоке!

...