当 运行 作为 Raspberry pi 上的服务时,脚本使用了过多的 cpu 能力
Script uses too many cpu power when run as a service on a Raspberry pi
我在 raspberry pi 上有这个代码片段 运行ning。它基本上拍摄进出我房间的人的照片。
import RPi.GPIO as GP
import os
import socket
def opencallback(channel):
print(GP.input(channel))
if GP.input(channel):
global closeEvent
closeEvent = 1
else:
global openEvent
openEvent = 1
def transmit(message):
s = socket.create_connection((host, port))
s.send(message)
s.close()
def capture(cam, gpiolist, quick):
GP.output(cam1, gpiolist[0])
GP.output(cam2, gpiolist[1])
GP.output(cam3, gpiolist[2])
if quick:
cmd = "raspistill -o capture_%d.jpg -t 2" % cam
else:
cmd = "raspistill -o capture_%d.jpg" % cam
os.system(cmd)
# init
GP.setwarnings(False)
GP.setmode(GP.BOARD)
cam1 = 7
cam2 = 11
cam3 = 12
doorIn = 40
ledOut = 38
GP.setup(cam1, GP.OUT) # camera Mux1
GP.setup(cam2, GP.OUT) # camera Mux2
GP.setup(cam3, GP.OUT) # camera Mux3
GP.setup(ledOut, GP.OUT) # LED OUT GPIO 20
GP.setup(doorIn, GP.IN) # Door detector in GPIO 21
GP.add_event_detect(doorIn, GP.BOTH, callback=opencallback)
GP.output(ledOut, False)
openEvent = 0
closeEvent = 0
host = '192.168.1.111'
port = 13579
# main
while True:
if openEvent == 1:
transmit("2-01")
capture(2, (False, True, False), True) # front cam
transmit("2-03")
openEvent = 0
else:
pass
if closeEvent == 1:
transmit("2-02")
GP.output(ledOut, True)
capture(3, (False, False, True), False)
GP.output(ledOut, False)
transmit("2-04")
closeEvent = 0
else:
pass
通常,我 运行 它只是通过命令行使用标准调用,它不会加载系统。
但是,我最近使用 systemd/systemctl 将其转换为服务,因为我想在启动 pi 时在后台加载该脚本。现在,这个脚本正在吞噬整个处理器内核(如 htop 所报告的)。在转换期间我没有对代码本身进行任何更改,当我 运行 以旧方式使用它时,它仍然可以正常工作。大多数时候,它只是 运行while 循环什么都不做,等待来自 GPIO 的回调,然后执行一些函数并返回到 while pass 行为。
我的问题是:是什么导致了两种执行方式的计算功耗差异?有办法解决这个问题吗?
edge-detection/callback代码是高效的,只有在事件发生时才会被调用。但是,top-level while True:
循环 极其 低效。
考虑以下修改:
try:
import Queue as queue # Python 2.x
except ImportError:
import queue # Python 3.x
eventQueue = queue.Queue()
def opencallback(channel):
eventQueue.put(GP.input(channel))
# ...your existing setup code here, specifically including:
GP.add_event_detect(doorIn, GP.BOTH, callback=opencallback)
while True:
event = eventQueue.get()
if event:
transmit("2-01")
capture(2, (False, True, False), True) # front cam
transmit("2-03")
else:
transmit("2-02")
GP.output(ledOut, True)
capture(3, (False, False, True), False)
GP.output(ledOut, False)
transmit("2-04")
请注意,这与 systemd 无关——你也会遇到与任何其他调用方法相同的 CPU 使用问题。
为什么不让回调直接触发打开和关闭事件的操作?只需让循环 运行 短 time.sleep
def opencallback(channel):
print(GP.input(channel))
if GP.input(channel):
transmit("2-02")
GP.output(ledOut, True)
capture(3, (False, False, True), False)
GP.output(ledOut, False)
transmit("2-04")
closeEvent = 0
else:
transmit("2-01")
capture(2, (False, True, False), True) # front cam
transmit("2-03")
我在 raspberry pi 上有这个代码片段 运行ning。它基本上拍摄进出我房间的人的照片。
import RPi.GPIO as GP
import os
import socket
def opencallback(channel):
print(GP.input(channel))
if GP.input(channel):
global closeEvent
closeEvent = 1
else:
global openEvent
openEvent = 1
def transmit(message):
s = socket.create_connection((host, port))
s.send(message)
s.close()
def capture(cam, gpiolist, quick):
GP.output(cam1, gpiolist[0])
GP.output(cam2, gpiolist[1])
GP.output(cam3, gpiolist[2])
if quick:
cmd = "raspistill -o capture_%d.jpg -t 2" % cam
else:
cmd = "raspistill -o capture_%d.jpg" % cam
os.system(cmd)
# init
GP.setwarnings(False)
GP.setmode(GP.BOARD)
cam1 = 7
cam2 = 11
cam3 = 12
doorIn = 40
ledOut = 38
GP.setup(cam1, GP.OUT) # camera Mux1
GP.setup(cam2, GP.OUT) # camera Mux2
GP.setup(cam3, GP.OUT) # camera Mux3
GP.setup(ledOut, GP.OUT) # LED OUT GPIO 20
GP.setup(doorIn, GP.IN) # Door detector in GPIO 21
GP.add_event_detect(doorIn, GP.BOTH, callback=opencallback)
GP.output(ledOut, False)
openEvent = 0
closeEvent = 0
host = '192.168.1.111'
port = 13579
# main
while True:
if openEvent == 1:
transmit("2-01")
capture(2, (False, True, False), True) # front cam
transmit("2-03")
openEvent = 0
else:
pass
if closeEvent == 1:
transmit("2-02")
GP.output(ledOut, True)
capture(3, (False, False, True), False)
GP.output(ledOut, False)
transmit("2-04")
closeEvent = 0
else:
pass
通常,我 运行 它只是通过命令行使用标准调用,它不会加载系统。
但是,我最近使用 systemd/systemctl 将其转换为服务,因为我想在启动 pi 时在后台加载该脚本。现在,这个脚本正在吞噬整个处理器内核(如 htop 所报告的)。在转换期间我没有对代码本身进行任何更改,当我 运行 以旧方式使用它时,它仍然可以正常工作。大多数时候,它只是 运行while 循环什么都不做,等待来自 GPIO 的回调,然后执行一些函数并返回到 while pass 行为。
我的问题是:是什么导致了两种执行方式的计算功耗差异?有办法解决这个问题吗?
edge-detection/callback代码是高效的,只有在事件发生时才会被调用。但是,top-level while True:
循环 极其 低效。
考虑以下修改:
try:
import Queue as queue # Python 2.x
except ImportError:
import queue # Python 3.x
eventQueue = queue.Queue()
def opencallback(channel):
eventQueue.put(GP.input(channel))
# ...your existing setup code here, specifically including:
GP.add_event_detect(doorIn, GP.BOTH, callback=opencallback)
while True:
event = eventQueue.get()
if event:
transmit("2-01")
capture(2, (False, True, False), True) # front cam
transmit("2-03")
else:
transmit("2-02")
GP.output(ledOut, True)
capture(3, (False, False, True), False)
GP.output(ledOut, False)
transmit("2-04")
请注意,这与 systemd 无关——你也会遇到与任何其他调用方法相同的 CPU 使用问题。
为什么不让回调直接触发打开和关闭事件的操作?只需让循环 运行 短 time.sleep
def opencallback(channel):
print(GP.input(channel))
if GP.input(channel):
transmit("2-02")
GP.output(ledOut, True)
capture(3, (False, False, True), False)
GP.output(ledOut, False)
transmit("2-04")
closeEvent = 0
else:
transmit("2-01")
capture(2, (False, True, False), True) # front cam
transmit("2-03")