【Python】python threading多线程实例

感知项目需要在sort中夹杂其他任务,跟踪结点的消息发送频率在15Hz以上,如果采用单线程的话会大大拖累sort的速度,因此采用 threading 实现双线程,本贴用一个例子来简述该过程。直接上代码:

import rospy
import threading
import time

'''
job()是子任务,
在主任务中一直循环检测,
当子任务的任务队列有任务时就执行
'''
def job():
    while True:
        if len(tasks)>0:
        	# 线程锁加锁
            lock1.acquire()
            # 修改共享变量
            id = tasks.pop(0)
            # 解除线程锁
            lock1.release()
            print(50*'-')
            print(id)
            print(tasks)
        	# 休眠1s,用来模拟子任务的计算耗时
        	time.sleep(1)
       	# 休眠,防止一直循环占用计算资源,也可不加  
        time.sleep(0.02)

def main():
	# 启动结点,模拟sort跟踪结点
    rospy.init_node('init', anonymous=True)
    rate = rospy.Rate(15)
    # lock是线程锁,防止一个线程在使用共享变量时被另一个线程更改
    global lock1
    lock1 = threading.Lock()
    # 另一个线程,用来做子任务
    thread1 = threading.Thread(target = job)
    # tasks用来表示子任务队列,任务可以是车牌识别等等
    global tasks
    tasks = []
    # k没啥用,只是控制一下循环次数,防止打印太多
    k = 0
    while k<4:
    	# 主任务
    	'''
    	主任务模拟sort.update,
    	当满足要求时,
    	将其添加到任务队列
    	'''
        for i in range(21):
            if i%5==0:
				# 线程锁加锁
                lock1.acquire()
                # 修改共享变量
                tasks.append(i)
                # 解除线程锁
                lock1.release()
        if k<=0:
        	# 只启动一次,实际使用过程中需要设计一下启动条件
            thread1.start()
        # 打印结果
        rospy.loginfo(tasks)
        k += 1
        rate.sleep()

if __name__ == '__main__':
    
    main()
    

打印结果如下:

zxc@zxc-MSI:~/catkin_ws$ rosrun plumbing_server_client test.py 
--------------------------------------------------
[INFO] [1664782453.415831]: [5, 10, 15, 20]
0
[5, 10, 15, 20]
[INFO] [1664782453.482819]: [5, 10, 15, 20, 0, 5, 10, 15, 20]
[INFO] [1664782453.549604]: [5, 10, 15, 20, 0, 5, 10, 15, 20, 0, 5, 10, 15, 20]
[INFO] [1664782453.616296]: [5, 10, 15, 20, 0, 5, 10, 15, 20, 0, 5, 10, 15, 20, 0, 5, 10, 15, 20]
--------------------------------------------------
5
[10, 15, 20, 0, 5, 10, 15, 20, 0, 5, 10, 15, 20, 0, 5, 10, 15, 20]
--------------------------------------------------
10
[15, 20, 0, 5, 10, 15, 20, 0, 5, 10, 15, 20, 0, 5, 10, 15, 20]
--------------------------------------------------
15
[20, 0, 5, 10, 15, 20, 0, 5, 10, 15, 20, 0, 5, 10, 15, 20]
--------------------------------------------------
20
[0, 5, 10, 15, 20, 0, 5, 10, 15, 20, 0, 5, 10, 15, 20]
--------------------------------------------------
0
[5, 10, 15, 20, 0, 5, 10, 15, 20, 0, 5, 10, 15, 20]
--------------------------------------------------
5
[10, 15, 20, 0, 5, 10, 15, 20, 0, 5, 10, 15, 20]
--------------------------------------------------
10
[15, 20, 0, 5, 10, 15, 20, 0, 5, 10, 15, 20]
--------------------------------------------------
15
[20, 0, 5, 10, 15, 20, 0, 5, 10, 15, 20]
--------------------------------------------------
20
[0, 5, 10, 15, 20, 0, 5, 10, 15, 20]
--------------------------------------------------
0
[5, 10, 15, 20, 0, 5, 10, 15, 20]
--------------------------------------------------
5
[10, 15, 20, 0, 5, 10, 15, 20]
--------------------------------------------------
10
[15, 20, 0, 5, 10, 15, 20]
--------------------------------------------------
15
[20, 0, 5, 10, 15, 20]
--------------------------------------------------
20
[0, 5, 10, 15, 20]
--------------------------------------------------
0
[5, 10, 15, 20]
--------------------------------------------------
5
[10, 15, 20]
--------------------------------------------------
10
[15, 20]
--------------------------------------------------
15
[20]
--------------------------------------------------
20
[]

主任务是从0-20遍历,当i是5的倍数时加入任务队列,此时子任务检测到任务队列并行执行任务。从结果来看,由于主任务的频率更高,因此很快执行完,子任务在之后会继续执行。

线程锁是为了防止各个线程同时修改内存,使得结果发生异常,因此在对共享变量进行操作时需要加锁,此时有且只有一个加锁的线程有权对内存进行修改,其他线程都被阻塞。

简单地说,各线程除了在线程锁加锁时是串行执行,其他时间都是并行执行。

参考

多线程解决rospy.spin()语句之后,程序不再往下执行问题

Python Lock acquire()实例讲解

内容概要:本文档详细介绍了在三台CentOS 7服务器(IP地址分别为192.168.0.157、192.168.0.158和192.168.0.159)上安装和配置Hadoop、Flink及其他大数据组件(如Hive、MySQL、Sqoop、Kafka、Zookeeper、HBase、Spark、Scala)的具体步骤。首先,文档说明了环境准备,包括配置主机名映射、SSH免密登录、JDK安装等。接着,详细描述了Hadoop集群的安装配置,包括SSH免密登录、JDK配置、Hadoop环境变量设置、HDFS和YARN配置文件修改、集群启动与测试。随后,依次介绍了MySQL、Hive、Sqoop、Kafka、Zookeeper、HBase、Spark、Scala和Flink的安装配置过程,包括解压、环境变量配置、配置文件修改、服务启动等关键步骤。最后,文档提供了每个组件的基本测试方法,确保安装成功。 适合人群:具备一定Linux基础和大数据组件基础知识的运维人员、大数据开发工程师以及系统管理员。 使用场景及目标:①为大数据平台建提供详细的安装指南,确保各组件能够顺利安装和配置;②帮助技术人员快速掌握Hadoop、Flink等大数据组件的安装与配置,提升工作效率;③适用于企业级大数据平台的建与维护,确保集群稳定运行。 其他说明:本文档不仅提供了详细的安装步骤,还涵盖了常见的配置项解释和故障排查建议。建议读者在安装过程中仔细阅读每一步骤,并根据实际情况调整配置参数。此外,文档中的命令和配置文件路径均为示例,实际操作时需根据具体环境进行适当修改。
在无线通信领域,天线阵列设计对于信号传播方向和覆盖范围的优化至关重要。本题要求设计一个广播电台的天线布局,形成特定的水平面波瓣图,即在东北方向实现最大辐射强度,在正东到正北的90°范围内辐射衰减最小且无零点;而在其余270°范围内允许出现零点,且正西和西南方向必须为零。为此,设计了一个由4个铅垂铁塔组成的阵列,各铁塔上的电流幅度相等,相位关系可自由调整,几何布置和间距不受限制。设计过程如下: 第一步:构建初级波瓣图 选取南北方向上的两个点源,间距为0.2λ(λ为电磁波波长),形成一个端射阵。通过调整相位差,使正南方向的辐射为零,计算得到初始相位差δ=252°。为了满足西南方向零辐射的要求,整体相位再偏移45°,得到初级波瓣图的表达式为E1=cos(36°cos(φ+45°)+126°)。 第二步:构建次级波瓣图 再选取一个点源位于正北方向,另一个点源位于西南方向,间距为0.4λ。调整相位差使西南方向的辐射为零,计算得到相位差δ=280°。同样整体偏移45°,得到次级波瓣图的表达式为E2=cos(72°cos(φ+45°)+140°)。 最终组合: 将初级波瓣图E1和次级波瓣图E2相乘,得到总阵的波瓣图E=E1×E2=cos(36°cos(φ+45°)+126°)×cos(72°cos(φ+45°)+140°)。通过编程实现计算并绘制波瓣图,可以看到三个阶段的波瓣图分别对应初级波瓣、次级波瓣和总波瓣,最终得到满足广播电台需求的总波瓣图。实验代码使用MATLAB编写,利用polar函数在极坐标下绘制波瓣图,并通过subplot分块显示不同阶段的波瓣图。这种设计方法体现了天线阵列设计的基本原理,即通过调整天线间的相对位置和相位关系,控制电磁波的辐射方向和强度,以满足特定的覆盖需求。这种设计在雷达、卫星通信和移动通信基站等无线通信系统中得到了广泛应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值