【问题标题】:Change in temperature file not detected未检测到温度文件的变化
【发布时间】:2021-12-08 08:37:54
【问题描述】:

我正在编写一个在我的树莓派 3b+ 上运行的 C++ 程序,它实时监控 CPU 的温度。
为了避免轮询,我使用 sys/inotify 库来观看 @ 987654322@ 用于文件更新。

但是,这似乎并没有发现对文件的更改。


对此进行测试:

  • 我在运行 main 时反复轮询文件(使用 cat),我看到文件中的值确实发生了变化,但 main 没有检测到变化。
  • 我试过tail -f /sys/class/thermal/thermal_zone0/temp,但是这也没有检测到任何变化。
  • 我创建了一个脚本来定期写入另一个文件,并让我的程序监视这个文件,它检测到那里的变化。

是否有可能在不传播 inotify 可检测到的事件的情况下更新此文件?我正在努力避免必须执行此文件的定期轮询不惜一切代价监控变化。

温度监视器.cpp

#include <iostream>
#include <unistd.h>
#include <sys/inotify.h>
#include <sys/types.h>

#include "./temperatureMonitor.hpp"


#define EVENT_SIZE  ( sizeof (struct inotify_event) )
#define BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )

namespace Performance {
  void TemperatureMonitor::monitor_temperature(void(*callback)(double)){

  };
  void TemperatureMonitor::monitor_temperature_file(){
    int length, i = 0;
    int fd;
    int wd;
    char buffer[BUF_LEN];
    fd = inotify_init();

    wd = inotify_add_watch(fd,"/sys/class/thermal/thermal_zone0/temp" , IN_MODIFY|IN_CREATE|IN_DELETE);

    while (true){

    length = read(fd, buffer, BUF_LEN);
    std::cout << "detected file change\n";   
    };
  };
};

main.cpp

#include "Performance/temperatureMonitor.hpp"

#define EVENT_SIZE  ( sizeof (struct inotify_event) )
#define BUF_LEN     ( 1024 ∗ ( EVENT_SIZE + 16 ) )


int main(){

  Performance::TemperatureMonitor tm = Performance::TemperatureMonitor();

  tm.monitor_temperature_file();

  return 0;
};

fwriter.go

package main
import (
    "os"
    "time"
)
func main() {
    f, err := os.Create("foo.txt")
    if err != nil {
        panic(err)
    }
    for {
        f.Write([]byte("test\n"))
        time.Sleep(time.Second)
    }
}

【问题讨论】:

    标签: c++ file-io operating-system filesystems


    【解决方案1】:

    它不是一个真正的文件,每当你读取它时,驱动程序都会被要求在其中生成数据。当其内容发生变化时,无法得到通知。投票就是答案。

    https://www.kernel.org/doc/html/latest/filesystems/sysfs.html

    在 read(2) 时,show() 方法应该填满整个缓冲区。记起 一个属性应该只导出一个值,或者一个数组 类似的值,所以这不应该那么贵。

    这允许用户空间进行部分读取和前向搜索 随意翻遍整个文件。如果用户空间回溯到 零或执行偏移量为“0”的 pread(2) show() 方法将 再次调用,重新配置,以填充缓冲区。

    您不必每次都打开和关闭它,寻找开头应该刷新它。虽然这可能不会节省太多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-18
      • 2021-06-04
      • 1970-01-01
      • 1970-01-01
      • 2021-06-17
      • 2017-03-04
      • 1970-01-01
      相关资源
      最近更新 更多