覆盆子pi python增加cpu使用率

时间:2017-07-18 15:55:51

标签: python memory-leaks raspberry-pi

我在树莓派上有以下python程序:

#! /usr/bin/env python
import time
import Adafruit_CharLCD as LCD
import RPi.GPIO as GPIO
import os
import glob
import os.path
from pathlib2 import Path
import datetime as dt
from datetime import datetime
import threading
import socket
from time import gmtime, strftime
import socket
from Adafruit_CharLCD import Adafruit_CharLCD
import re

#############################lcd screen####################
lcd_rs = 25
lcd_en = 24
lcd_d4 = 23
lcd_d5 = 17
lcd_d6 = 18
lcd_d7 = 22
lcd_backlight = 4

lcd_columns = 16
lcd_rows = 2

lcd = LCD.Adafruit_CharLCD(lcd_rs, lcd_en, lcd_d4, lcd_d5, lcd_d6, lcd_d7, lcd_columns, lcd_rows, lcd_backlight)


#############################temp reader########################
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

base_dir = '/sys/bus/w1/devices/'
#divice_folder = glob.glob(base_dir + '28-0115818f20ff')[0]
#device_file = divice_folder + '/w1_slave'

def temp_sen():
        for folder in os.listdir(base_dir):
                #print folder
                if re.match(r'[^w1_bus]', folder):
                        divice_folder = glob.glob(base_dir + folder)[0]
                        print divice_folder
                        device_file = divice_folder + '/w1_slave'
                        print device_file
                        return device_file
thefile = temp_sen()
def read_temp_raw():
    f = open(thefile, 'r')
    lines = f.readlines()
    f.close()
    return lines
def read_temp():
    lines = read_temp_raw()
    while lines[0].strip()[-3:] != 'YES':
        time.sleep(0.2)
        lines = read_temp_raw()
    equals_pos = lines[1].find('t=')
    if equals_pos != -1:
        temp_string =  lines[1][equals_pos+2:]
        temp_c = float(temp_string) / 1000.0
        #temp_f = temp_c * 9.0 / 5.0 + 32.0
        #temp_c_str = "{:.3f}".format(temp_c)
        #temp_f_str = "{:.3f}".format(temp_f)
                #temp_c_str = str(round(temp_c, 1))
                #temp_f_str = str(round(temp_f, 1))
        #temps = 'C: ' + temp_c_str + '\n\rF: ' + temp_f_str
        return temp_c


####################keypad###########################
class keypad():
    KEYPAD = [
    [1,2,3],
    [4,5,6],
    [7,8,9],
    ["*",0,"#"]
    ]
    ROW = [21,6,13,19]
    COLUMN = [12,16,20]

    def __init__(self):
        GPIO.setmode(GPIO.BCM);
    def getKey(self):
        for j in range(len(self.COLUMN)):
            GPIO.setup(self.COLUMN[j], GPIO.OUT)
            GPIO.output(self.COLUMN[j], GPIO.LOW)

        for i in range(len(self.ROW)):
            GPIO.setup(self.ROW[i], GPIO.IN, pull_up_down=GPIO.PUD_UP)

        rowVal = -1
        for i in range(len(self.ROW)):
            tmpRead = GPIO.input(self.ROW[i])
            if tmpRead == 0:
                rowVal = i

        if (rowVal < 0) or (rowVal > 3):
            self.exit()
            return
        for j in range(len(self.COLUMN)):
            GPIO.setup(self.COLUMN[j], GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

        GPIO.setup(self.ROW[rowVal], GPIO.OUT)
        GPIO.output(self.ROW[rowVal], GPIO.HIGH)

        colVal = -1
        for j in range(len(self.COLUMN)):
            tmpRead = GPIO.input(self.COLUMN[j])
            if tmpRead == 1:
                colVal = j

        if (colVal < 0) or (colVal > 2):
            self.exit()
            return

        self.exit()
        return self.KEYPAD[rowVal][colVal]

    def exit(self):
        for i in range(len(self.ROW)):
            GPIO.setup(self.ROW[i], GPIO.IN, pull_up_down=GPIO.PUD_UP)
        for j in range(len(self.COLUMN)):
            GPIO.setup(self.ROW[i], GPIO.IN, pull_up_down=GPIO.PUD_UP)
#######################logfile###########################
def log_file():
    if temp_con.t != 0:
                DTnow = str(datetime.now().strftime('%H:%M'))
                today = str(datetime.now().date())
                tmp = read_temp()
                temp = str(tmp)
                myfile = Path("/home/pi/TempLog/" + today + ".txt")
                if myfile.is_file:
                        log = open(str(myfile), "a")
                        log.write(DTnow + " " + temp + "C" + "\n")
                else:
                        log = open(str(myfile),"a+")
                        log.write(DTnow + " " + temp + "C" + "\n")
                threading.Timer(2, log_file).start()
#########################relay control###################
relay_pin = 27
def on():
    GPIO.setup(relay_pin, GPIO.OUT)
    GPIO.output(relay_pin, GPIO.HIGH)
def off():
    GPIO.setup(relay_pin, GPIO.OUT)
    GPIO.output(relay_pin, GPIO.LOW)        
######temp controler############
class temp_con:
    def __init__(self):
        self._t = 0

    @property
    def t(self):
        return self._t

    @t.setter
    def t(self, value):     
        self._t = value

#############physical inputs################
def phys_in():
        while True:
                kp = keypad()   
                list = ['']
                digit = None
                while True:
                    digit = kp.getKey()
                    if digit != None and digit != '*' and digit != '#':
                        list.append(str(digit))
                        time.sleep(.5)
                        digit = None
                    elif digit == '*':
                        while True:
                                        log_file()
                            stop = kp.getKey()
                            temp_con.t = int(''.join(list))
                            Rtemp = str(read_temp())
                            if read_temp() <= temp_con.t and stop != '#':
                                #time.sleep(1)
                                #lcd.clear()

                                print "relay activated!"
                                #lcd.message("relay activated!")

                                time.sleep(.5)
                                lcd.clear()

                                lcd.message(Rtemp)

                                print Rtemp
                                on()

                            elif read_temp() >= temp_con.t and stop != '#':
                                #time.sleep(1)
                                #lcd.clear()

                                print "relay deactivated!"
                                #lcd.message("relay deactivated!")
                                time.sleep(.5)
                                                lcd.clear()

                                                lcd.message(Rtemp)

                                                print Rtemp
                                    off()

                                elif stop == '#':
                                    temp_con.t = 0
                                    del list[:]
                                    lcd.clear()

                                    print "oven is now off!"
                                    lcd.message("oven is now off!")

                                    off()
                                    digit = None
                                    stop = None
                                    break   

######################main#########################
if __name__ == '__main__':
        phys_in()

随着这个程序的运行,它变得越来越慢。

基本流程是使用输入键盘上的温度然后点击&#39; *&#39;键。程序然后从温度传感器读取并比较2个数字并根据天气响应传感器温度高于或低于输入温度。如果&#39;#&#39;按下键,输入温度设置为0,一切都重置为默认值。

程序设置为在启动时运行并开始大约需要4秒钟才能完成,但在大约10分钟后,它需要10秒以上并继续降级。

我怀疑某处有内存泄漏,但我无法找到它。谁能发现问题?

编辑:忘了提到这是关于树莓派。在使用top检查进程时,我发现内存使用量没有增加,但CPU使用率却在增加。在2分钟内从2%上升到近30%。

Edit2:这是cProfile的结果:

541055函数调用813.851秒

订购者:标准名称

ncalls tottime percall cumtime percall filename:lineno(function)

    1    0.000    0.000  813.851  813.851 <string>:1(<module>)

  180    0.005    0.000    0.868    0.005 Adafruit_CharLCD.py:169(clear)

  180    0.021    0.000    1.758    0.010 Adafruit_CharLCD.py:234(message)

 1225    0.112    0.000    2.051    0.002 Adafruit_CharLCD.py:261(write8)

 8755    1.243    0.000    1.997    0.000 Adafruit_CharLCD.py:296(_delay_microseconds)

 2450    0.113    0.000    0.368    0.000 Adafruit_CharLCD.py:302(_pulse_enable)

18375    0.154    0.000    0.229    0.000 GPIO.py:190(output)

 2450    0.119    0.000    0.261    0.000 GPIO.py:81(output_pins)

 5723    0.331    0.000    0.659    0.000 TempManualControlsOven.py:124(exit)

  181    0.062    0.000  198.064    1.094 TempManualControlsOven.py:130(log_file)

  180    0.005    0.000    0.011    0.000 TempManualControlsOven.py:149(off)
    1    0.254    0.254  813.851  813.851 TempManualControlsOven.py:166(phys_in)

  723    0.030    0.000  789.489    1.092 TempManualControlsOven.py:52(read_temp_raw)

  723    0.068    0.000  789.574    1.092 TempManualControlsOven.py:57(read_temp)

    1    0.000    0.000    0.000    0.000 TempManualControlsOven.py:86(__init__)

 5723    0.534    0.000    1.617    0.000 TempManualControlsOven.py:88(getKey)

  181    0.010    0.000    0.113    0.001 pathlib2.py:1172(__new__)

  181    0.002    0.000    0.002    0.000 pathlib2.py:1182(_init)

  181    0.038    0.000    0.064    0.000 pathlib2.py:177(parse_parts)

  181    0.005    0.000    0.007    0.000 pathlib2.py:413(splitroot)

  181    0.005    0.000    0.007    0.000 pathlib2.py:58(_py2_fsencode)

  181    0.016    0.000    0.091    0.001 pathlib2.py:797(_parse_args)

  181    0.009    0.000    0.101    0.001 pathlib2.py:826(_from_parts)

  181    0.005    0.000    0.007    0.000 pathlib2.py:849(_format_parsed_parts)

  181    0.015    0.000    0.022    0.000 pathlib2.py:866(__str__)

  181    0.001    0.000    0.001    0.000 threading.py:1008(daemon)

  181    0.006    0.000    0.174    0.001 threading.py:1046(Timer)

  181    0.009    0.000    0.168    0.001 threading.py:1067(__init__)

  181    0.004    0.000    0.004    0.000 threading.py:1152(currentThread)

  543    0.018    0.000    0.089    0.000 threading.py:242(Condition)

  543    0.064    0.000    0.071    0.000 threading.py:260(__init__)

  180    0.002    0.000    0.002    0.000 threading.py:294(_release_save)

  180    0.002    0.000    0.006    0.000 threading.py:297(_acquire_restore)

  180    0.003    0.000    0.013    0.000 threading.py:300(_is_owned)

  180    0.016    0.000    0.127    0.001 threading.py:309(wait)

  362    0.006    0.000    0.089    0.000 threading.py:542(Event)

  362    0.013    0.000    0.083    0.000 threading.py:561(__init__)

  181    0.001    0.000    0.001    0.000 threading.py:570(isSet)

 1086    0.011    0.000    0.011    0.000 threading.py:59(__init__)

  181    0.008    0.000    0.141    0.001 threading.py:603(wait)

  181    0.011    0.000    0.011    0.000 threading.py:629(_newname)

  361    0.002    0.000    0.002    0.000 threading.py:64(_note)

  181    0.022    0.000    0.124    0.001 threading.py:656(__init__)

  181    0.006    0.000    0.012    0.000 threading.py:709(_set_daemon)

  181    0.019    0.000    0.220    0.001 threading.py:726(start)

22901    0.056    0.000    0.056    0.000 {RPi._GPIO.input}

35727    0.130    0.000    0.130    0.000 {RPi._GPIO.output}

    1    0.000    0.000    0.000    0.000 {RPi._GPIO.setmode}

80314    0.517    0.000    0.517    0.000 {RPi._GPIO.setup}

  181    0.002    0.000    0.002    0.000 {built-in method __new__ of type object at 0x2d4c48}

  362    0.032    0.000    0.032    0.000 {built-in method now}

  181    0.005    0.000    0.005    0.000 {hasattr}

  724    0.005    0.000    0.005    0.000 {intern}

  543    0.005    0.000    0.005    0.000 {isinstance}

 2450    0.010    0.000    0.010    0.000 {iter}

28983    0.039    0.000    0.039    0.000 {len}

  901    0.106    0.000    0.106    0.000 {method 'acquire' of 'thread.lock' objects}

 1268    0.006    0.000    0.006    0.000 {method 'append' of 'list' objects}

  722    0.107    0.000    0.107    0.000 {method 'close' of 'file' objects}

  181    0.001    0.000    0.001    0.000 {method 'date' of 'datetime.datetime' objects}

    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

  722    0.010    0.000    0.010    0.000 {method 'find' of 'str' objects}

 2450    0.015    0.000    0.015    0.000 {method 'items' of 'dict' objects}

  362    0.004    0.000    0.004    0.000 {method 'join' of 'str' objects}

  181    0.002    0.000    0.002    0.000 {method 'lstrip' of 'str' objects}

  723  789.152    1.091  789.152    1.091 {method 'readlines' of 'file' objects}

  361    0.001    0.000    0.001    0.000 {method 'release' of 'thread.lock' objects}

  181    0.000    0.000    0.000    0.000 {method 'reverse' of 'list' objects}

  181    0.003    0.000    0.003    0.000 {method 'split' of 'str' objects}

  181    0.029    0.000    0.029    0.000 {method 'strftime' of 'datetime.date' objects}

  722    0.006    0.000    0.006    0.000 {method 'strip' of 'str' objects}

  181    0.019    0.000    0.019    0.000 {method 'write' of 'file' objects}

  904    0.261    0.000    0.261    0.000 {open}

 1045    0.003    0.000    0.003    0.000 {ord}

28621    0.091    0.000    0.091    0.000 {range}

  723    0.005    0.000    0.005    0.000 {thread.allocate_lock}

  181    0.001    0.000    0.001    0.000 {thread.get_ident}

  181    0.059    0.000    0.059    0.000 {thread.start_new_thread}

  182   19.033    0.105   19.033    0.105 {time.sleep}

273246 0.754 0.000 0.754 0.000 {time.time}

唯一向我发出的是阅读线。

1 个答案:

答案 0 :(得分:1)

Raspberry Pi有一个小型ARM(我认为1.2Ghz)的进程。它耗尽了很多cpu,因为没有太多东西可以使用。就像你有25马力的汽车或500马力。有一个限制。