【python】多线程(3)queue队列之不同延时时长的参数调用问题

本文主要是介绍【python】多线程(3)queue队列之不同延时时长的参数调用问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

链接1:【python】多线程(笔记)(1)
链接2:【python】多线程(笔记)(2)Queue队列

0.问题描述

两个线程,但是不同延时时长,导致数据输出频率不同,但是又想基于其中的最大频率实时输出数据(比如线程一与线程二均用来描述某个物体的运动,但是线程一每2秒输出数据,线程二每1秒输出数据,输出数据方式为[线程一数据,线程二数据],希望屏幕每1秒打印出该数据),但是队列中,以后进先出队列为例,数据每取出之后队列就少一个数据,这就需要用global全局变量作为中间值。

1.示例代码

两个线程,func1与func2,
func1的参数从0开始每2秒自增一次并输入到中间队列中,
func2每1秒从中间队列取出最新的参数并打印到屏幕上:如果队列不为空,则打印最新参数;如果为空,则打印历史参数

中间队列设为q
则逻辑如下:
在这里插入图片描述示例代码如下所示:
注意代码逻辑顺序,非常重要!!!

import threading
import time
import queueq=queue.LifoQueue()#后进先出队列,队列长度无限制global qqq
global ppp
ppp=-1#线程二的初始值,为了区别这里给ppp赋值-1
qqq=-2#线程一的初始值
#这两个参数赋值为负仅为了鉴别线程是否会被执行
#由于线程一在下面的threads中优先于线程二执行,屏幕上不会打印出-1与-2#线程一
def func1():#func1每2秒自增一次global qqqq1=0for i in range(5):q1=q1+1qqq=q1q.put(qqq)#最新的qqq值写入q队列中print ("线程一q1: %s, %s" %(qqq,time.ctime()))time.sleep(2)#每2秒向q线程中填入新值#线程二
def func2():#func2每1秒向线程中取值#global qqqglobal pppfor i in range(10):if q.qsize()==0:#如果q线程为空,赋历史值qqqqq=pppprint ("线程二q2: %s, %s" %(qqqqq,time.ctime()))else:#如果q线程不为空,赋新值q2=q.get([i])#func2获取q队列数据,因为后进先出,因此获取的都是最新数据ppp=q2print ("线程二q2: %s, %s" %(q2,time.ctime()))time.sleep(1)#每1秒向q线程中取值#定义线程
threads = []
t1 = threading.Thread(target=func1)#这里谁是t1谁先执行
threads.append(t1)
t2 = threading.Thread(target=func2)#这里谁是t2谁后执行
threads.append(t2)#主程序/主线程
if __name__ == '__main__':for t in threads:#按照顺序执行threads的内容t.setDaemon(True)t.start()t.join()#子线程优先print ("qqq %s" %qqq)#查看qqq的最新值print ("all over %s" %time.ctime())#查看结束时刻print("queue size= %s" %queue.Queue.qsize(q))#查看队列大小

输出结果:
在这里插入图片描述只看q1,每两秒自增并输出一次,正确
只看q2,每一秒输出一次,输出的都是q1的最新值,正确

错误情况一:给队列提前赋值

导致队列不为空,影响后续输出
错误代码:(第11行提前给队列赋值)

import threading
import time
import queueq=queue.LifoQueue()#后进先出队列,队列长度无限制global qqq
global ppp
ppp=-1#线程二的初始值为了区别这里给ppp赋值-1
qqq=-2#先给qqq赋值,然后写入队列中否则func2一开始无法获取数据
q.put(qqq)#提前给队列赋值#线程一
def func1():#func1每2秒自增一次global qqqq1=0for i in range(5):q1=q1+1qqq=q1q.put(qqq)#最新的qqq值写入q队列中print ("线程一q1: %s, %s" %(qqq,time.ctime()))time.sleep(2)#每2秒向q线程中填入新值#线程二
def func2():#func2每1秒向线程中取值#global qqqglobal pppfor i in range(10):if q.qsize()==0:#如果q线程为空,赋历史值qqqqq=pppprint ("线程二q2: %s, %s" %(qqqqq,time.ctime()))else:#如果q线程不为空,赋新值q2=q.get([i])#func2获取q队列数据,因为后进先出,因此获取的都是最新数据ppp=q2print ("线程二q2: %s, %s" %(q2,time.ctime()))time.sleep(1)#每1秒向q线程中取值#定义线程
threads = []
t1 = threading.Thread(target=func1)#, args=[qqq])
threads.append(t1)
t2 = threading.Thread(target=func2)#, args=[qqq])
threads.append(t2)#主程序/主线程
if __name__ == '__main__':for t in threads:#按照顺序执行threads的内容t.setDaemon(True)t.start()t.join()#子线程优先print ("qqq %s" %qqq)#查看qqq的最新值print ("all over %s" %time.ctime())#查看结束时刻print("queue size= %s" %queue.Queue.qsize(q))#查看队列大小

错误结果:
在这里插入图片描述由于队列被提前赋值,导致17:43:16秒时队列不为空,队列中最开始被赋值的-2被取出

错误情况二:线程逻辑顺序反了

正确的情况是func1先自增、将参数写入队列,func2再取数
反过来的话,func2先取数,此时若未提前定义队列,可能会引起错误

错误代码:

import threading
import time
import queueq=queue.LifoQueue()#后进先出队列,队列长度无限制global qqq
global ppp
ppp=-1#线程二的初始值为了区别这里给ppp赋值-1
qqq=-2#先给qqq赋值,然后写入队列中否则func2一开始无法获取数据
#q.put(qqq)#先给qqq赋值,然后写入队列中否则func2一开始无法获取数据#线程一
def func1():#func1每2秒自增一次global qqqq1=0for i in range(5):q1=q1+1qqq=q1q.put(qqq)#最新的qqq值写入q队列中print ("线程一q1: %s, %s" %(qqq,time.ctime()))time.sleep(2)#每2秒向q线程中填入新值#线程二
def func2():#func2每1秒向线程中取值#global qqqglobal pppfor i in range(10):if q.qsize()==0:#如果q线程为空,赋历史值qqqqq=pppprint ("线程二q2: %s, %s" %(qqqqq,time.ctime()))else:#如果q线程不为空,赋新值q2=q.get([i])#func2获取q队列数据,因为后进先出,因此获取的都是最新数据ppp=q2print ("线程二q2: %s, %s" %(q2,time.ctime()))time.sleep(1)#每1秒向q线程中取值#定义线程
threads = []
t1 = threading.Thread(target=func2)#, args=[qqq])
threads.append(t1)
t2 = threading.Thread(target=func1)#, args=[qqq])
threads.append(t2)#主程序/主线程
if __name__ == '__main__':for t in threads:#按照顺序执行threads的内容t.setDaemon(True)t.start()t.join()#子线程优先print ("qqq %s" %qqq)#查看qqq的最新值print ("all over %s" %time.ctime())#查看结束时刻print("queue size= %s" %queue.Queue.qsize(q))#查看队列大小

错误结果:线程二先被启动而且输出错误数据
在这里插入图片描述

这里

#定义线程
threads = []
t1 = threading.Thread(target=func2)#, args=[qqq])
threads.append(t1)
t2 = threading.Thread(target=func1)#, args=[qqq])
threads.append(t2)

导致func2先被执行,正确的应该是

#定义线程
threads = []
t1 = threading.Thread(target=func1)#, args=[qqq])
threads.append(t1)
t2 = threading.Thread(target=func2)#, args=[qqq])
threads.append(t2)

这篇关于【python】多线程(3)queue队列之不同延时时长的参数调用问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1025120

相关文章

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

Python+PyQt5实现多屏幕协同播放功能

《Python+PyQt5实现多屏幕协同播放功能》在现代会议展示、数字广告、展览展示等场景中,多屏幕协同播放已成为刚需,下面我们就来看看如何利用Python和PyQt5开发一套功能强大的跨屏播控系统吧... 目录一、项目概述:突破传统播放限制二、核心技术解析2.1 多屏管理机制2.2 播放引擎设计2.3 专

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很

python+opencv处理颜色之将目标颜色转换实例代码

《python+opencv处理颜色之将目标颜色转换实例代码》OpenCV是一个的跨平台计算机视觉库,可以运行在Linux、Windows和MacOS操作系统上,:本文主要介绍python+ope... 目录下面是代码+ 效果 + 解释转HSV: 关于颜色总是要转HSV的掩膜再标注总结 目标:将红色的部分滤

SpringBoot启动报错的11个高频问题排查与解决终极指南

《SpringBoot启动报错的11个高频问题排查与解决终极指南》这篇文章主要为大家详细介绍了SpringBoot启动报错的11个高频问题的排查与解决,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一... 目录1. 依赖冲突:NoSuchMethodError 的终极解法2. Bean注入失败:No qu

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

在C#中调用Python代码的两种实现方式

《在C#中调用Python代码的两种实现方式》:本文主要介绍在C#中调用Python代码的两种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#调用python代码的方式1. 使用 Python.NET2. 使用外部进程调用 Python 脚本总结C#调

Python下载Pandas包的步骤

《Python下载Pandas包的步骤》:本文主要介绍Python下载Pandas包的步骤,在python中安装pandas库,我采取的方法是用PIP的方法在Python目标位置进行安装,本文给大... 目录安装步骤1、首先找到我们安装python的目录2、使用命令行到Python安装目录下3、我们回到Py