我是python的新手,并开始学习一些高级概念。这里我使用python队列来消费和生成线程。这是一个线程安全吗?在这里,我将列表项添加到队列并在使用者线程中检索它。有没有最好的方法呢?
from queue import Queue
import threading
import time
class producer(threading.Thread):
def __init__(self, list_of_numbers):
threading.Thread.__init__(self)
self.list_items = list_of_numbers
def run(self):
for i in self.list_items:
queue.put(str(i))
class consumer(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
while queue.not_empty:
queue_ret = queue.get()
print("Retrieved", queue_ret)
queue = Queue()
producers = producer([10,20,5,4,3,2,1])
consumers = consumer()
producers.start()
consumers.start()
producers.join()
consumers.join()
答案 0 :(得分:1)
Docs明确声明Queue是线程安全的:
Queue模块实现多生产者,多消费者队列。它 当信息必须时,在线程编程中特别有用 在多个线程之间安全地交换。
答案 1 :(得分:1)
首先使用队列初始化您的消费者类。
然后在消费者线程类的末尾添加queue.task_done()。这将告诉线程在将来的queue.get()调用中忽略该队列项。最终这意味着你的队列将“空”并且线程将完成他们的工作。
class consumer(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def run(self):
while queue.not_empty:
queue_ret = self.queue.get()
print("Retrieved", queue_ret)
self.queue.task_done()
# to start your threads, for example 5 threads
for i in range(5):
consumers = consumer(queue)
consumers.start()
答案 2 :(得分:0)
要完成消费者线程,您可以将sentinel值推送到队列中,如下所示:
from queue import Queue
import threading
import time
class producer(threading.Thread):
def __init__(self, list_of_numbers):
threading.Thread.__init__(self)
self.list_items = list_of_numbers
def run(self):
for i in self.list_items:
queue.put(str(i))
print("Producer Finished")
class consumer(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
done = False
while not done:
queue_ret = queue.get()
if queue_ret is None:
done = True
else:
print("Retrieved", queue_ret)
queue.task_done()
print("Consumer Finished")
queue = Queue()
producers = [producer([10,20,5,4,3,2,1])]
consumers = [consumer()]
for producer in producers:
producer.start()
for consumer in consumers:
consumer.start()
for producer in producers:
producer.join()
for consumer in consumers:
queue.put(None)
for consumer in consumers:
consumer.join()
print("Finished")