4

我想使用 Python(在 Linux 下)获取硬盘的温度。我目前正在调用hddtempsubprocess.popen但我经常调用它,以至于它是我脚本中的性能瓶颈。我认为应该可以做类似于问题 4193514的事情?

4

3 回答 3

5

您可以将 hddtemp 作为守护程序运行(-d 选项),然后使用套接字来查询它 - 默认为端口 7634。

编辑:查看一些执行此操作的代码

于 2012-05-02T21:56:08.253 回答
2

扩展@gnibbler 在他的主要评论中建议的内容,缓存方法呢?这是一个愚蠢的简单示例,只是为了展示这个概念:

from collection import defaultdict

class CachedValue(object):
    def __init__(self):
        self.timestamp = -1
        self._value = None

    @property 
    def value(self):
        return self._value

    @value.setter 
    def value(self, val):
        self._value = val 
        self.timestamp = time.time()

    def isOld(self, seconds):
        return (time.time() - self.timestamp) >= seconds

>>> _cached = defaultdict(CachedValue)
>>> _cached['hddtemp'].isOld(10)
True
>>> _cached['hddtemp'].value = 'Foo'
>>> _cached['hddtemp'].isOld(10)
False
# (wait 10 seconds)
>>> _cached['hddtemp'].isOld(10)
True

在您的具体情况下:

def reportHDD(self):
    if self._cached['hddtemp'].isOld(10):
        self._cached['hddtemp'].value = self.getNewHDDValue()
    return self._cached['hddtemp'].value

这种方法实际上更像是缓存昂贵操作的通用解决方案。在较大的应用程序中,CachedValue 可以很容易地替换为简单的 memcached/redis 查找,它为您维护自己的 TTL 值。但在小范围内,这只是组织本地缓存值的一种奇特方式。

于 2012-05-02T21:33:11.530 回答
2

我在谷歌上搜索了一段时间,无论我如何格式化我的搜索,这个命中一直接近顶部。我在所有主机上都安装了 smartmontools 和至少 python 2.7.6,我不想安装一个新包来将硬盘临时数据传输到石墨/statsd,所以我做了以下操作。

我不是开发人员,我不知道 python(很明显)所以这是我 1-2 天的尝试来弄清楚它。我很尴尬,无法在这里发布所有代码,但这里是主要交易::

enter code here
#!/usr/bin/env python
import os

import subprocess

import multiprocessing

def grab_hdd_temp(hdd, queue):
  for line in subprocess.Popen(['smartctl', '-a', str('/dev/' + hdd)], stdout=subprocess.PIPE).stdout.read().split('\n'):
    if ( 'Temperature_Celsius' in line.split() ) or ('Temperature_Internal' in line.split() ):
      queue.put([hdd, line.split()[9]])

def hddtmp_dict(hdds_list):
  procs = []
  queue = multiprocessing.Queue()
  hddict={}
  for hdd in hdds_list:
    p = multiprocessing.Process(target=grab_hdd_temp, args=(hdd, queue))
    procs.append(p)
    p.start()
  for _ in procs:
    val = queue.get()
    hddict[val[0]]=val[1]
    p.join()
  return hddict

if __name__ == '__main__':
  hdds_list = [ x for x in os.listdir('/sys/block/') if x.startswith('sd') ]
  hddict = hddtmp_dict(hdds_list)
  for k in hddict:
      print(k, hddict[k])

在我的存储服务器上,这会在 2 秒内返回 38 个驱动器的完整列表,而在 50 秒内依次遍历所有磁盘。也就是说,在 40 芯盒子上,负载从 1.08 左右跃升至 3.50。所以,随心所欲吧。我试图找到一种方法来使用 proc 或可能基于另一个堆栈溢出的 fcntl 我发现拉数据而不是使用 subprocess.popen 但是嗯。

现在是凌晨 2 点 22 分,我需要开始回家了。在那里,我将尝试概述上面的代码片段,并说出我认为一切都在做什么,但我希望它有点不言自明。

对不起kludge代码。我认为在这一点上缓冲是更好的方法,但这是一个很酷的练习。如果您不想安装 hddtemp 并且我认为缓冲区 + 以上可能是最好的选择。仍在试图弄清楚这一点,因为我还不明白如何上课。

我希望这可以帮助别人。

于 2016-06-14T07:25:58.123 回答