在python进程中更新变量

2022-04-10 00:00:00 python python-multiprocessing

问题描述

我正在使用套接字将命令从一个RPI发送到另一个RPI。接收RPI在其接收到命令"TURN RIGHT"时启动伺服(通过运行Y伺服功能),并在其接收到"STOP"时通过终止进程来停止旋转伺服。伺服位置从x=50的一半开始。问题是主代码中的伺服位置没有更新,因此下次运行该进程时,它会再次从50开始。

我需要更新/更改一个python进程中的值(让YServerBreak它的While循环。例如,WHILE STATE==True:,因此当状态更新为FALSE时,WHILE循环中断,并且可以返回值x而不是终止进程),或者让进程更新主实例中的变量(X)。

接收代码:

import socket
from multiprocessing import Process 
import RPi.GPIO as gpio
import time
gpio.setmode(gpio.BCM)

ps = 27
ys = 28

gpio.setup(ps,gpio.OUT)
gpio.setup(ys,gpio.OUT)


pitchS = gpio.PWM(ps,50)
pitchS.start(0)


x = 50

def Yservo(): #x is starting position / current position
    global x
    while 1:
        x += 1
        pitchS.ChangeDutyCycle(x)
        time.sleep(1)
        print(x)
        if x >= 100:
            while 1:
                pass


server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(('', 6666))
print ("UDPServer Waiting for client on port 6666")


try:
    while True:  
        dataFromClient, address = server_socket.recvfrom(256)
        data = str(dataFromClient.decode('utf-8'))
        data = data.split(',')
        if data[0] == 'turnRight':
            TS = Process(target=Yservo,args=())
            TS.daemon = True
            TS.start()
            #TS.join()
        if data[0] == 'stop':
            TS.terminate()
            TS.join()

except:
    print('STOP! wait a minute')
    TS.terminate()
    TS.join()


解决方案

我建议让您的进程保持活动状态,或者每次都派生/终止它,并让它每隔1秒监听一个队列,以便从主进程获得订单。此外,只要您不终止子进程,YServer子进程中的内部While循环将最大限度地占用一个内核Ifx>=100,这是不可取的。此版本将记住您之前停止的位置:

import socket
from multiprocessing import Process, Queue
import RPi.GPIO as gpio
import time
import Queue

gpio.setmode(gpio.BCM)
start_position=50
ps = 27
ys = 28

gpio.setup(ps,gpio.OUT)
gpio.setup(ys,gpio.OUT)
pitchS = gpio.PWM(ps,50)
pitchS.start(0)

def Yservo(q, start_position):

    command = None
    x = start_position
    while True:
        try:
            command = q.get(False)
        except Queue.Empty:
            pass
        if command == "turn_right" and x < 100:
            x += 1
            pitchS.ChangeDutyCycle(x)
        time.sleep(1)
        print(x)


q = Queue()
TS = Process(target=Yservo,args=(q,start_position))
TS.daemon = True
TS.start()

try:
    while True:  
        dataFromClient, address = server_socket.recvfrom(256)
        data = str(dataFromClient.decode('utf-8'))
        data = data.split(',')
        if data[0] == 'turnRight':
            q.put("turn_right")
        if data[0] == 'stop':
            q.put("stop")
except:
    print('STOP! wait a minute')
    TS.terminate()
    TS.join()

q.get()将阻止您的代码执行,但通过传递False布尔值并捕获Queue.Empty异常,您可以尝试以非阻塞方式使用队列中的对象。

相关文章