Почему чтение из /sys/bus/ занимает так много времени?

Я работаю над проектом, который требует данных датчика от датчика температуры. При доступе к файлу с помощью open(), а затем read() мы обнаружили, что это занимает слишком много времени. У нас есть отдельная проблема для read(), занимающая больше всего времени (примерно 1 секунду). Есть ли более быстрая альтернатива read() или я использую ее неправильно? Код:

import time, os, socket

#External thermometer address: 28-031897792ede

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

temp_sensor = '/sys/bus/w1/devices/28-031897792ede/w1_slave'

def temp_raw():
    f = open(temp_sensor, 'r')
    lines = f.readlines()
    f.close()
    return lines

def read_temp():

    lines = temp_raw()
    while lines[0].strip()[-3:] != 'YES':
        lines = temp_raw()

    temp_output = lines[1].find('t=')

    if temp_output != -1:
        temp_string = lines [1].strip()[temp_output+2:]
        temp_c = float(temp_string) / 1000.0
        return round(temp_c, 1)

while True:
    temp_raw()

person Aditya Kondapuram    schedule 08.05.2019    source источник
comment
lines = f.read() будьте осторожны, возможно, вы имеете в виду lines = f.readlines()   -  person Jean-François Fabre    schedule 09.05.2019
comment
файл бинарный? вы используете окна?   -  person Jean-François Fabre    schedule 09.05.2019
comment
этот цикл, вероятно, бесконечен: while lines[0].strip()[-3:] != 'YES': lines = temp_raw() так как вы читаете файл каждый раз, поэтому, если он совпадает один раз, он совпадает навсегда   -  person Jean-François Fabre    schedule 09.05.2019
comment
stackoverflow.com/questions/30294146 /   -  person Matthew Barlowe    schedule 09.05.2019
comment
@Jean-FrançoisFabre Файл представляет собой простой текстовый файл, состоящий всего из двух строк. Тестирование temp_raw() на время показывает, что readlines() занимает почти 1 секунду, но не другая функция, насколько я могу судить.   -  person Aditya Kondapuram    schedule 09.05.2019
comment
Есть несколько проблем с этим в функции и эффективности. Прежде всего, я не уверен, что вы пытаетесь сделать, поскольку ваша основная программа полностью игнорирует read_temp. У вас есть неэффективный бесконечный цикл, который читает файл и завершает работу без какой-либо обработки. Пожалуйста, опишите, что вы пытаетесь сделать с этим. Я не уверен, почему вы пропустили примеры руководств по работе с файлами для этой реализации.   -  person Prune    schedule 09.05.2019
comment
@Prune это был пример кода для датчика температуры. Он использовал read_temp() для нормализации данных датчика до значения, которое имеет смысл. Чтобы выяснить, почему это заняло так много времени, мы протестировали каждую часть и обнаружили, что проблема была в temp_raw() и, в частности, в readlines().   -  person Aditya Kondapuram    schedule 09.05.2019
comment
Пожалуйста, исправьте свой код. В том, что вы написали, нет ссылки на readlines. Опять же, какова цель этого кода? Даже если вы вызываете read_temp, кажется, что все, что делает эта функция, — это находит одну строку в файле и извлекает конкретное поле float. С этой целью он читает весь файл. Эту функциональность, вероятно, лучше реализовать с помощью команды ОС (например, awk в UNIX).   -  person Prune    schedule 09.05.2019
comment
(хотя awk использует системный вызов read(), точно так же, как Python и любая другая программа пользовательского пространства, которая взаимодействует с файлоподобными объектами в UNIX, так что вы не увидите значительного улучшения в блокировке вызова одним языком по сравнению с чужое).   -  person Charles Duffy    schedule 09.05.2019
comment
Тем не менее, чтение с устройства, в отличие от обычного файла, будет иметь характеристики производительности, которые зависят от драйвера (обычно ядра) для этого устройства и аппаратного обеспечения, которое за ним стоит. Если аппаратное обеспечение отправляет обновление каждую секунду, а драйвер блокируется до тех пор, пока не будет доступно следующее? Угадайте, что вы ждете до секунды... и это не имеет ничего общего с тем, какой язык программирования вы используете.   -  person Charles Duffy    schedule 09.05.2019


Ответы (1)


Вы открываете файл, который на самом деле не является обычным файлом файловой системы — это символьное устройство. Системные вызовы узлов устройств в Linux напрямую реализуются специальным драйвером, который регистрируется для обработки пары старший/младший номера, поэтому их производительность зависит от реализации этого драйвера в операционной системе.

Высокая задержка характерна для драйвера w1-therm; это происходит независимо от того, какой язык программирования вы используете.

В соответствии со спецификацией оборудования на https://www.maximintegrated.com/en/products/sensors/DS18B20.html, частота обновления составляет ~750 мс при создании 12-битных выходных данных. Таким образом, вы смотрите примерно на 3/4 секунды на считывание температуры, даже если все остальное абсолютно идеально.

Откровенно говоря, более высокая частота обновления не имеет смысла в контексте датчика температуры — если физическая температура самого устройства меняется так быстро, что вам нужно больше, чем измерение каждую секунду (принимая во внимание время, необходимое для тепло на самом деле передается на датчик), у вас есть большие проблемы.

person Community    schedule 09.05.2019