#python #multithreading #queue
Вопрос:
Довольно легко отправлять или получать данные через потоки, используя модуль очереди, когда вы делаете что-то одновременно, но я не понял, как отправить что-то в поток, а затем правильно ожидать возврата.
В приведенном ниже примере я ожидал отправить что-то потоку для обработки, а затем получить результат, но функция t.queue.get()
в основном получает то, что только что отправлено выше, вместо того, чтобы ждать возвращения потока. Как я могу это обойти?
#!/usr/bin/env python3
from threading import Thread
from queue import Queue
class MyThread(Thread):
queue:Queue
def __init__(self, *args, **kwargs):
super().__init__()
self.queue = Queue()
self.daemon = True
# receives a name, then prints "Hello, name!"
def run(self):
while True:
val = self.queue.get()
if not val:
break
self.queue.put(f'Hello, {val}!')
def main():
t = MyThread()
t.start()
# sends string to thread
t.queue.put('Jurandir')
# expects to receive "Hello, Jurandir!",
# but "Jurandir" is immediately returned
ret = t.queue.get()
print(ret)
if __name__ == '__main__':
main()
Комментарии:
1. Две очереди. По одному для каждого направления (основной->рабочий, рабочий->>основной)?
2. @Аарон, не думай об этой возможности. Это сработало отлично, спасибо!
Ответ №1:
Дело в том, что вы получаете предполагаемый результат сразу из очереди, а работник все еще не добавил результат. Вы можете разделить их на «входную очередь» и «очередь результатов». А затем подождите в главном потоке, пока в очереди не появится какой-нибудь вывод.
#!/usr/bin/env python3
from threading import Thread, Lock
from queue import Queue
class MyThread(Thread):
def __init__(self, *args, **kwargs):
super().__init__()
self.input_queue = Queue()
self.results_queue = Queue()
self.daemon = True
# receives a name, then prints "Hello, name!"
def run(self):
while True:
val = self.input_queue.get()
if not val:
break
self.results_queue.put(f'Hello, {val}!')
def main():
t = MyThread()
t.start()
# sends string to thread
t.input_queue.put('Jurandir')
ret = t.results_queue.get()
while ret is None:
ret = t.results_queue.get()
print(ret)
if __name__ == '__main__':
main()