【问题标题】:How can I use Python Threading with parameter passing between threads?如何使用 Python Threading 在线程之间传递参数?
【发布时间】:2020-09-13 23:25:32
【问题描述】:

1. 总结问题 我正在使用 Python 2 和运行 Raspbian Buster 的 Raspberry Pi 4。试图限制我的程序从使用套接字通过 UDP 连接发送其数据的 Android 设备读取传感器数据的速度。 IE:我将其构建为一个小型激光绊线应用程序,开始时,我想在每次传感器值下降到某个数字以下时增加一个计数累加器,表明激光绊倒。但是,数据读取速度如此之快,以至于每次传感器水平下降时,计数都会增加很多次。我怎样才能每 X 秒读取一次 UDP 数据?

2。 描述你的尝试

  • 我已经尝试过 time.sleep(),但根据我的阅读,这是一个阻塞函数,经过测试,它确实阻止了我的程序通过 UDP 套接字更新传感器数据
  • 我尝试过线程,但我不知道如何将传感器数据从一个线程传递到另一个线程。
  • 我研究了 join(),但遇到的技术文档对初学者不太友好。
  • 这里的一些帖子建议设置客户端/服务器接口,但我也不知道该怎么做。

3. 在适当的时候,显示一些代码 这是我目前在线程解决方案方面的进展。我正在使用名为 SensorUDP 的 Android 应用程序,并且在环境光传感器打开并激活发送数据的情况下,该程序将读取 UDP 数据并打印它。即使没有 UDP 数据,它仍然会运行计数线程。

import socket
from struct import *
import time
import threading

#We have 0-92 over a 1024 byte buffer representing distinct
#sensors being sent over UDP from my android smartphone
#this test program im only pulling byte 56 for Ambient Light sensing
#a laser shining into my phones sensor has 30,000-50,000 lums so anything
#less then that range must mean the laser was tripped


#UDP = SOCK_DGRAM, AF_INET = Internet
UDP_IP = "192.168.1.149" #my rpi4 address
print "Receiver IP: ", UDP_IP
UDP_PORT = 5000 #arbitrary for now but needs to match my androids broadcast
print "Port: ", UDP_PORT
sock = socket.socket(socket.AF_INET, # Internet
                    socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT)) #complete the binding

running = True
count = 0
laserOn = 1000 #using a low lums to test so I dont have to use laser every time
aLight = 0
result_available = threading.Event() #.set() this when the data is recieved
threadTimer = 5

def calcAmbLight():

# Continuously read from the UDP socket
   
    while running:
       
        data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
        #the data from the app Im using to push the sensor data needs to
        #be unpacked
        aLight = "%.1f" %unpack_from ('!f', data, 56)
        print ("Ambient Light = ", aLight)

def displayCount():
    count = 0
    while running:
        time.sleep(1)
        #how to pass aLight into this thread from the other thread?
        if aLight < laserOn:
            count = count + 1

        print("Current aLight: ",aLight)
        print("Current Count: ", count)
       
if __name__ == '__main__':
              
    #create a basicthread to run calcAmbLight
    calcAmb = threading.Thread(target= calcAmbLight)
    calcAmb.start()
   
    dispCount = threading.Thread(target = displayCount)
    dispCount.start()

【问题讨论】:

    标签: python multithreading sockets udp


    【解决方案1】:

    当前设置的问题是由于您没有在calcAmbLight() 中将aLight 声明为全局。将其声明为全局变量应该允许它工作。

    def calcAmbLight():
        global aLight  # Set the global aLight, instead of a local stack variable
    
        while running:
    
            data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
            #the data from the app Im using to push the sensor data needs to
            #be unpacked
            aLight = "%.1f" %unpack_from ('!f', data, 56)
            print ("Ambient Light = ", aLight)
    

    【讨论】:

    • 他说当信号跳闸时他得到了一个信号变化......另一个循环只是不断增加计数器的次数......
    • 如果他们使用发布的代码,其他线程将不会接受更改。全局变量aLight 永远不会被修改,只有calcAmbLight 的局部变量被更改。该问题专门询问如何在线程之间传递变量。
    • 感谢罗伯特提出使用全局变量声明的想法,但它似乎不起作用,除非我再次做错了什么。在将两个线程之间使用的变量声明为全局变量后,尝试运行程序将针对声明为全局变量且不在同一线程中的任何“x”说“NameError:未定义全局名称‘x’”作为声明,即:在 calcAmbLight() def 中声明全局 aLight 变量,然后尝试在 displayCount() 中使用 aLight 会导致此错误。在全局空间中将 aLight 声明为全局 aLight 也不起作用
    • 请忽略最后一条评论,因为我误解了,显然我必须将 aLight 的声明保留在全局空间中,然后在函数中引用 aLight 时,我必须在函数中声明全局 aLight 以让函数知道我我说的是在全局空间中声明的 aLight。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-30
    • 1970-01-01
    • 2018-12-21
    • 1970-01-01
    • 2014-01-15
    • 1970-01-01
    相关资源
    最近更新 更多