当前位置: 首页 > news >正文

【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队列之不同延时时长的参数调用问题

链接1:【python】多线程(笔记)(1) 链接2:【python】多线程(笔记)(2)Queue队列 0.问题描述 两个线程,但是不同延时时长,导致数据输出…...

Java开发常见基础问题

Java开发的多个方面,包括但不限于Java基础知识、多线程并发、JVM、框架使用、数据库、设计模式、网络编程等。 以下是一些常见的问题以及回答的方向: Java 开发技术常见问题(一) Java 基础知识 对象和类的区别是什么&#xff1…...

大数据组件doc

1.flink Apache Flink Documentation | Apache Flink 2.kafka Apache Kafka 3.hbase Apache HBase ™ Reference Guide 4.zookeeper ZooKeeper: Because Coordinating Distributed Systems is a Zoo 5.spark Overview - Spark 3.5.1 Documentation 6.idea组件(…...

Docker Hub 国内镜像源配置

Docker Hub 国内镜像源配置 Docker Hub 国内镜像源是指在国内境内提供 Docker 镜像服务的镜像源。由于国际网络带宽等问题,国内用户下载 Docker 镜像通常速度较慢。因此,为了解决这个问题,一些国内的公司和组织提供了 Docker 镜像的国内镜像…...

持续总结中!2024年面试必问 20 道 Kafka面试题(一)

一、Kafka 的基础概念有哪些? Kafka 是一个分布式流处理平台,由 LinkedIn 开发,并于 2011 年成为 Apache 软件基金会的一部分。以下是 Kafka 的一些基础概念: Broker: Kafka 集群由多个 Broker 组成,每个 Broker 存储…...

Linux共享内存创建和删除

最近项目中使用到了共享内存记录下 创建共享内存: 删除共享内存: 代码: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <sys/mman.h> #include <sys/stat.h> #include <u…...

微信小程序如何自定义tabbar

微信小程序自定义底部tabbar是一个提升用户体验和增加小程序个性化的重要功能。以下是自定义底部tabbar的步骤&#xff0c;以供参考&#xff1a; 一、自定义tabbar的重要性 微信小程序默认的底部导航栏&#xff08;tabbar&#xff09;样式和布局是固定的&#xff0c;开发者无…...

【并发程序设计】15.信号灯(信号量)

15.信号灯(信号量) Linux中的信号灯即信号量是一种用于进程间同步或互斥的机制&#xff0c;它主要用于控制对共享资源的访问。 在Linux系统中&#xff0c;信号灯作为一种进程间通信&#xff08;IPC&#xff09;的方式&#xff0c;与其他如管道、FIFO或共享内存等IPC方式不同&…...

【操作与配置】VS2017与MFC环境配置

【操作与配置】VS2017与MFC环境配置 概述 Visual Studio 是一款强大且多功能的集成开发环境&#xff08;IDE&#xff09;&#xff0c;适用于软件开发人员和团队。使用此应用程序&#xff0c;您可以构建和调试现代Web应用程序&#xff0c;并利用扩展帮助探索几乎任何编程语言。…...

遥感影像信息提取

刘老师&#xff08;副教授&#xff09;&#xff0c;来自双一流重点高校&#xff0c;长期从事GIS/RS/3S技术及其生态环境领域中的应用等方面的研究和教学工作&#xff0c;并参与GIS的二次开发&#xff0c;发表多篇sci论文&#xff0c;具有资深的技术底蕴和专业背景。 专题一&am…...

LRU算法

文章目录 LRU算法LRU 如何实现LinkedHashMap来实现的LRU算法的缓存HashMap实现LRU算法的缓存 LRU算法 LRU&#xff08;Least Recently Used&#xff09;算法可以使用哈希表和双向链表来实现。哈希表用于快速查找数据&#xff0c;双向链表用于记录数据的访问顺序。以下是LRU算法…...

JVM运行时数据区 - 程序计数器

运行时数据区 Java虚拟机在执行Java程序的过程中&#xff0c;会把它管理的内存划分成若干个不同的区域&#xff0c;这些区域有各自的用途、创建及销毁时间&#xff0c;有些区域随着虚拟机的启动一直存在&#xff0c;有些区域则随着用户线程的启动和结束而建立和销毁&#xff0…...

1.JAVA小项目(零钱通)

一、说明 博客内容&#xff1a;B站韩顺平老师的视频&#xff0c;以及代码的整理。此项目分为两个版本&#xff1a; 面向过程思路实现面向对象思路实现 韩老师视频地址&#xff1a;【【零基础 快速学Java】韩顺平 零基础30天学会Java】 https://www.bilibili.com/video/BV1fh4…...

Redis这一篇就够了

一.概述 Redis是什么&#xff1f; Redis是远程服务字典服务&#xff0c;是一个开源的使用ANSI C语言编写&#xff0c;支持网络&#xff0c;可基于内存亦可持久化的日志型&#xff0c;Key-Value数据库&#xff0c;并提供多种语言的API。 redis会周期性把更新的数据写入磁盘或把…...

Java web应用性能分析之【jvisualvm远程连接云服务器】

Java web应用性能分析之【java进程问题分析概叙】-CSDN博客 Java web应用性能分析之【java进程问题分析工具】-CSDN博客 前面整理了java进程问题分析和分析工具&#xff0c;现在可以详细看看jvisualvm的使用&#xff0c;一般java进程都是部署云服务器&#xff0c;或者托管IDC机…...

springboot发送短信验证码,结合redis 实现限制,验证码有效期2分钟,有效期内禁止再次发送,一天内发送超3次限制

springboot结合redis发送短信验证码,实现限制发送操作 前言(可忽略)实现思路正题效果图示例手机号不符合规则校验图成功发送验证码示例图redis中缓存随机数字验证码&#xff0c;2分钟后失效删除redis缓存图验证码有效期内 返回禁止重复发送图验证码24小时内发送达到3次&#xf…...

【Python】使用 Pandas 统计每行数据中的空值

缘分让我们相遇乱世以外 命运却要我们危难中相爱 也许未来遥远在光年之外 我愿守候未知里为你等待 我没想到为了你我能疯狂到 山崩海啸没有你根本不想逃 我的大脑为了你已经疯狂到 脉搏心跳没有你根本不重要 &#x1f3b5; 邓紫棋《光年之外》 在数据分析…...

1pannel部署onenav导航容器编排模板

onenav导航 1pannel部署onenav导航容器编排模板 networks:1panel-network:external: true services:onenav:container_name: onenavimage: helloz/onenav:latestlabels:createdBy: Appsnetworks:- 1panel-networkports:- 127.0.0.1:{port}:80environment:- TZAsia/Shanghaivol…...

linux--实时性优化

linux--实时性优化 1 介绍2 实时性需求3 代表性实时系统4 嵌入式系统嵌入式软件系统结构处理器时钟节拍多任务机制任务调度方式任务调度算法时间片调度算法优先级调度算法基于优先级的时间片调度算法 5 cyclictest 测试工具命令说明命令分析参数含义 6 linux 实时性改进某版本上…...

React-基础样式控制

组件基础样式方案 React组件基础的样式控制有两种方式 1、行内样式&#xff08;不推荐&#xff09; 属性名是多个单词的需要使用驼峰写法 也可以把样式都提取到一个变量里&#xff0c;再赋值到style里 2、class类名控制 classnames优化类名控制 classnames是一个简单的JS库&…...

制作ChatPDF之前端Vue搭建(二)

前端界面 接上篇: 制作ChatPDF之Elasticsearch8.13.4搭建&#xff08;一&#xff09; 为了实现一个基于 Vue.js 的前端应用&#xff0c;用户可以上传 PDF 文件&#xff0c;输入查询&#xff0c;并在输出框中显示查询结果&#xff0c;你需要以下步骤&#xff1a; 初始化 Vue …...

汽车IVI中控开发入门及进阶(二十一):DAB和FM 收音机

前言: 在过去的十年里,数字收音机对车载娱乐产生了重大影响。现在,几乎每辆新车都标配了这项技术,这也是我们60%以上的人收听收音机的方式。甚至有传言称,在不久的将来,将永久关闭调频发射机,使许多车载收音机过时。但一些相对年轻的汽车在工厂里仍然没有安装DAB,而且…...

智能sql LLM

DB-GPT&#xff1a;彻底改变数据库与私有LLM技术的交互 智能SQL生成&#xff1a;后端技术与LLM的完美结合 智能SQL生成&#xff1a;后端技术与LLM的完美结合_llm sql-CSDN博客 GitHub - eosphoros-ai/DB-GPT: AI Native Data App Development framework with AWEL(Agentic Wor…...

大聪明教你学Java | 深入浅出聊 Stream.parallel()

前言 &#x1f34a;作者简介&#xff1a; 不肯过江东丶&#xff0c;一个来自二线城市的程序员&#xff0c;致力于用“猥琐”办法解决繁琐问题&#xff0c;让复杂的问题变得通俗易懂。 &#x1f34a;支持作者&#xff1a; 点赞&#x1f44d;、关注&#x1f496;、留言&#x1f4…...

图解大模型分布式并行各种通信原语

背景 在分布式集群上执行大模型任务时候&#xff0c;往往使用到数据并行&#xff0c;流水线并行&#xff0c;张量并行等技术&#xff0c;这些技术本质上也就是对数据进行各种方案的切分&#xff0c;然后放到不同的节点上运算。不同节点在计算的过程中需要对数据分发或者同步等…...

张大哥笔记:下一个风口是什么?

我们经常会问&#xff0c;下一个风口是什么&#xff1f;我们可以大胆预测一下&#xff0c;2024年的风口是什么呢&#xff1f; 40年前&#xff0c;如果你会开车&#xff0c;那就是响当当的铁饭碗&#xff1b; 30年前&#xff0c;如果你会英语和电脑&#xff0c;那也绝对是个人才…...

AI去衣技术中的几何着色:揭秘数字时尚的魔法

在数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;正以前所未有的速度改变我们的生活&#xff0c;从智能家居到自动驾驶汽车&#xff0c;再到个性化医疗。然而&#xff0c;AI的影响远不止于此。它正在重塑我们对艺术、设计和时尚的理解。特别是在数字时尚领域&#…...

Leecode---技巧---只出现一次的数字 / 多数元素

题解&#xff1a; 利用异或运算 a⊕a 0 的性质&#xff0c;可用来消除所有出现了两次的元素&#xff0c;最后剩余的即为所得。 class Solution { public:int singleNumber(vector<int>& nums){// 初始化为0int ans 0;for(int x: nums){// 异或操作ans ^ x;}retur…...

为图片设置经纬度信息

一、java实现 小编看了很多技术博客&#xff0c;但是测试要么下载的jar包中的api和博客对不上&#xff0c;要么就是不对&#xff0c;总之没实现 Java 读取图片信息 java 写入 exif 信息 使用Java读取和修改图片的Exif信息 java获取图片的GPS信息 https://drewnoakes.com/code/e…...

密码和密钥的联系与区别

密码和密钥是两个非常重要的概念&#xff0c;但容易混淆这两者&#xff0c;以下内容介绍了它们的联系和区别&#xff1a; 一、定义 密码&#xff08;Password&#xff09;&#xff0c;在日常语境中&#xff0c;通常指的是个人为了验证自己的身份而设置的一段秘密的字符序列&am…...