我想使用 Python(在 Linux 下)获取硬盘的温度。我目前正在调用hddtemp
,subprocess.popen
但我经常调用它,以至于它是我脚本中的性能瓶颈。我认为应该可以做类似于问题 4193514的事情?
3 回答
您可以将 hddtemp 作为守护程序运行(-d 选项),然后使用套接字来查询它 - 默认为端口 7634。
编辑:查看一些执行此操作的代码。
扩展@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 值。但在小范围内,这只是组织本地缓存值的一种奇特方式。
我在谷歌上搜索了一段时间,无论我如何格式化我的搜索,这个命中一直接近顶部。我在所有主机上都安装了 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 并且我认为缓冲区 + 以上可能是最好的选择。仍在试图弄清楚这一点,因为我还不明白如何上课。
我希望这可以帮助别人。