Python中queue分类有几种,怎样实现多线程通信
Admin 2022-07-25 群英技术资讯 417 次浏览
python3 queue分三类:
他们的导入方式分别是:
from queue import Queue from queue import LifoQueue from queue import
具体方法见下面引用说明。
Queue
对象已经包含了必要的锁,所以你可以通过它在多个线程间多安全地共享数据。 当使用队列时,协调生产者和消费者的关闭问题可能会有一些麻烦。一个通用的解决方法是在队列中放置一个特殊的值,当消费者读到这个值的时候,终止执行。
例如:
from queue import Queue from threading import Thread # 用来表示终止的特殊对象 _sentinel = object() # A thread that produces data def producer(out_q): for i in range(10): print("生产") out_q.put(i) out_q.put(_sentinel) # A thread that consumes data def consumer(in_q): while True: data = in_q.get() if data is _sentinel: in_q.put(_sentinel) break else: print("消费", data) # Create the shared queue and launch both threads q = Queue() t1 = Thread(target=consumer, args=(q,)) t2 = Thread(target=producer, args=(q,)) t1.start() t2.start()
结果:
本例中有一个特殊的地方:消费者在读到这个特殊值之后立即又把它放回到队列中,将之传递下去。这样,所有监听这个队列的消费者线程就可以全部关闭了。 尽管队列是最常见的线程间通信机制,但是仍然可以自己通过创建自己的数据结构并添加所需的锁和同步机制来实现线程间通信。最常见的方法是使用 Condition
变量来包装你的数据结构。下边这个例子演示了如何创建一个线程安全的优先级队列。
import heapq import threading class PriorityQueue: def __init__(self): self._queue = [] self._count = 0 self._cv = threading.Condition() def put(self, item, priority): with self._cv: heapq.heappush(self._queue, (-priority, self._count, item)) self._count += 1 self._cv.notify() def get(self): with self._cv: while len(self._queue) == 0: self._cv.wait() return heapq.heappop(self._queue)[-1]
使用队列来进行线程间通信是一个单向、不确定的过程。通常情况下,你没有办法知道接收数据的线程是什么时候接收到的数据并开始工作的。不过队列对象提供一些基本完成的特性,比如下边这个例子中的task_done()
和 join()
:
from queue import Queue from threading import Thread class Producer(Thread): def __init__(self, q): super().__init__() self.count = 5 self.q = q def run(self): while self.count > 0: print("生产") if self.count == 1: self.count -= 1 self.q.put(2) else: self.count -= 1 self.q.put(1) class Consumer(Thread): def __init__(self, q): super().__init__() self.q = q def run(self): while True: print("消费") data = self.q.get() if data == 2: print("stop because data=", data) # 任务完成,从队列中清除一个元素 self.q.task_done() break else: print("data is good,data=", data) # 任务完成,从队列中清除一个元素 self.q.task_done() def main(): q = Queue() p = Producer(q) c = Consumer(q) p.setDaemon(True) c.setDaemon(True) p.start() c.start() # 等待队列清空 q.join() print("queue is complete") if __name__ == '__main__': main()
结果:
设置俩队列,一个是要做的任务队列todo_queue
,一个是已经完成的队列done_queue
。
每次执行线程,先从todo_queue
队列里取出一个值,然后执行完,放入done_queue
队列。
如果todo_queue
为空,就退出。
import logging import logging.handlers import threading import queue log_mgr = None todo_queue = queue.Queue() done_queue = queue.Queue() class LogMgr: def __init__(self, logpath): self.LOG = logging.getLogger('log') loghd = logging.handlers.RotatingFileHandler(logpath, "a", 0, 1) fmt = logging.Formatter("%(asctime)s %(threadName)-10s %(message)s", "%Y-%m-%d %H:%M:%S") loghd.setFormatter(fmt) self.LOG.addHandler(loghd) self.LOG.setLevel(logging.INFO) def info(self, msg): if self.LOG is not None: self.LOG.info(msg) class Worker(threading.Thread): global log_mgr def __init__(self, name): threading.Thread.__init__(self) self.name = name def run(self): while True: try: task = todo_queue.get(False) if task: log_mgr.info("HANDLE_TASK: %s" % task) done_queue.put(1) except queue.Empty: break return def main(): global log_mgr log_mgr = LogMgr("mylog") for i in range(30): todo_queue.put("data"+str(i)) workers = [] for i in range(3): w = Worker("worker"+str(i)) workers.append(w) for i in range(3): workers[i].start() for i in range(3): workers[i].join() total_num = done_queue.qsize() log_mgr.info("TOTAL_HANDLE_TASK: %d" % total_num) exit(0) if __name__ == '__main__': main()
输出日志文件结果:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章主要介绍了python中的opencv 图像分割与提取,图像中将前景对象作为目标图像分割或者提取出来。对背景本身并无兴趣分水岭算法及GrabCut算法对图像进行分割及提取。具体实现过程需要的朋友可以参考下面文章详细介绍
这篇文章主要给大家介绍了关于Python中os模块的简单使用及重命名操作的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
本篇文章给大家带来了关于Python的相关知识,其中主要整理了自动化脚本的相关问题,包括了自动化阅读网页新闻、自动化数据探索、自动发送多封邮件等等内容,下面一起来看一下,希望对大家有帮助。
scikit-learn是一个开源Python语言机器学习工具包,它涵盖了几乎所有主流机器学习算法的实现,并且提供了一致的调用接口。它基于Numpy和scipy等Python数值计算库,提供了高效的算法实现
本篇文章给大家带来了关于Python的相关知识,主要介绍了python文件数据分析治理提取,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下。
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008