Как Python Очередь знает, что это будет пусто? - PullRequest
1 голос
/ 02 марта 2020

Я хотел бы понять, откуда очередь знает, что она не получит никаких новых элементов. В следующем примере очередь будет бесконечно ждать, когда поток tputter не будет запущен (я полагаю, потому что до сих пор в него ничего не помещалось). Если tputter запущен, он ждет между «путами», пока не появится что-то новое, и как только все закончится, он остановится. Но как tgetter узнает, окажется ли что-то новое в очереди или нет?

import threading
import queue
import time

q = queue.Queue()

def getter():
    for i in range(5):
        print('worker:', q.get())
        time.sleep(2)


def putter():
    for i in range(5):
        print('putter: ', i)
        q.put(i)
        time.sleep(3)

tgetter = threading.Thread(target=getter)
tgetter.start()
tputter = threading.Thread(target=putter)
#tputter.start()

1 Ответ

2 голосов
/ 02 марта 2020

Обычный способ сделать это - использовать шаблон «Ядовитая таблетка». По сути, производитель и потребитель договариваются об особом объекте «ядовитой пилюли», который производитель может загрузить в очередь, что будет означать, что больше не будет отправлено ни одного элемента, а потребитель может отключиться.

Итак, в вашем примере это выглядело бы так:

import threading
import queue
import time

q = queue.Queue()
END = object()

def getter():
    while True:
        item = q.get()
        if item == END:
           break
        print('worker:', item)
        time.sleep(2)


def putter():
    for i in range(5):
        print('putter: ', i)
        q.put(i)
        time.sleep(3)
    q.put(END)

tgetter = threading.Thread(target=getter)
tgetter.start()
tputter = threading.Thread(target=putter)
#tputter.start()

Это немного надумано, так как производитель жестко запрограммирован всегда посылать пять товаров, поэтому вы должны представить, что потребитель не Не знаю заранее, сколько товаров отправит производитель.

...