Многопоточная очередь

#python #multithreading #priority-queue

#python #многопоточность #приоритет-очередь

Вопрос:

У меня есть очередь, обработанная в отдельном потоке. Когда я заполняю задания из основного потока, только последнее задание обрабатывается несколько раз. Это работает, если я блокирую очередь join() между каждым put() , но это не удовлетворяет моим потребностям. В Python 3:

 Q = PriorityQueue()

def processQ():
    while True :
        if not Q.empty():
            job = Q.get(False)
            job[1]()
            Q.task_done()

def fill():
    for i in range(0,100):
        Q.put(((1, Q.qsize()), lambda: print(i)))

def main():
    Thread(target=lambda: processQ()).start()
    fill()
  

И на выходе получается :

 99
99
99
99
etc... 100 times
  

Я прочитал кое-что о ее решении с помощью многопроцессорной обработки, но это кажется очень сложным для простого поведения, которое я хочу…

Еще одна вещь, которую я не понимаю, это почему я должен включать Q.qsize() в put в противном случае a

Ошибка типа: неупорядочиваемые типы: function() < функция()

возникает проблема. Мне не приходилось этого делать в Python 2.7

Я был бы очень рад, если бы вы могли мне помочь

****** РЕДАКТИРОВАТЬ ******

Таким образом, вы НЕ можете использовать лямбда-функцию, как я. Вы ДОЛЖНЫ поместить функцию с аргументами в очередь с кортежем, подобным этому:

 for i in range(0,100):
     Q.put(((1, Q.qsize()), (print, i)))

def processQ():
    while True :
        if not Q.empty():
            job = Q.get(False)
            func = job[1][0]  # [0] is the priority, [1:] are the arguments
            args = job[1][1:]
            func(*args)
            Q.task_done()
  

Теперь вопрос в том, ПОЧЕМУ?

Комментарии:

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

2. что сказал @erip, и что касается WHY? вы, возможно, захотите прочитать кое-что из этого: docs.python-guide.org/en/latest/writing/gotchas

3. хорошо, спасибо! ссылка очень полезная!

4. docs.python.org/3.5/library/queue.html на самом деле здесь написано: «Внутренне модуль использует блокировки для временной блокировки конкурирующих потоков; однако он не предназначен для обработки повторного входа в поток». имеется в виду threadsafe.