概述
stats
stats
是菜单栏中的 macOS 系统监视器。
github上的地址在这里。
Stats
是一个允许您监控 macOS 系统的应用程序。macOS 10.13 (High Sierra)
及更高版本目前支持统计信息。
安装
手动安装
您可以在此处下载最新版本。
这将下载一个名为Stats.dmg
. 打开它并将应用程序移动到应用程序文件夹。
Homebrew
要使用 Homebrew 安装它,请打开终端应用程序并键入:
brew install --cask stats
Stats
是一个允许您监控 macOS
系统的应用程序。
- 电池电量
- 蓝牙设备
- CPU 利用率
- 磁盘利用率
- 风扇控制
- GPU 利用率
- 内存使用情况
- 网络使用情况
- 传感器信息(温度/电压/功率)
如何减少 Stats 的能源影响或 CPU 使用率?
Stats 尽可能提高效率。但是定期读取一些数据并不是一项便宜的任务。每个模块都有自己的“价格”。因此,如果您想减少 Stats 对能源的影响,您需要禁用一些 Stats 模块。效率最低的模块是传感器和蓝牙。在某些情况下,禁用这些模块最多可将 CPU 使用率和电源效率降低 50%。
主要代码分析
stats
程序基本上是使用swift
写成,代码量并不多,如果是刚学习swift
的可以以这个为demo
来进行相应的学习,从中可以体会到macos
的编程基础,而swift
在这个项目中的结构也非常的清晰,通过这个项目,相信对swift
的使用会有更进一步的了解。
cpu显示
获取cpu
相关信息,通过函数获取到相关的信息,通过计算得出了要显示的内容,显示在相应的位置上,这个是整个代码的核心功能,因为stat
最重要的一点是展示系统的信息。
public override func read() {
let result: kern_return_t = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &self.numCPUsU, &self.cpuInfo, &self.numCpuInfo)
if result == KERN_SUCCESS {
self.CPUUsageLock.lock()
self.usagePerCore = []
for i in 0 ..< Int32(numCPUs) {
var inUse: Int32
var total: Int32
if let prevCpuInfo = self.prevCpuInfo {
inUse = self.cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_USER)]
- prevCpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_USER)]
+ self.cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_SYSTEM)]
- prevCpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_SYSTEM)]
+ self.cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_NICE)]
- prevCpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_NICE)]
total = inUse + (self.cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_IDLE)]
- prevCpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_IDLE)])
} else {
inUse = self.cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_USER)]
+ self.cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_SYSTEM)]
+ self.cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_NICE)]
total = inUse + self.cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_IDLE)]
}
if total != 0 {
self.usagePerCore.append(Double(inUse) / Double(total))
}
}
self.CPUUsageLock.unlock()
let showHyperthratedCores = Store.shared.bool(key: "CPU_hyperhreading", defaultValue: false)
if showHyperthratedCores || !self.hasHyperthreadingCores {
self.response.usagePerCore = self.usagePerCore
} else {
var i = 0
var a = 0
self.response.usagePerCore = []
while i < Int(self.usagePerCore.count/2) {
a = i*2
if self.usagePerCore.indices.contains(a) && self.usagePerCore.indices.contains(a+1) {
self.response.usagePerCore.append((Double(self.usagePerCore[a]) + Double(self.usagePerCore[a+1])) / 2)
}
i += 1
}
}
if let prevCpuInfo = self.prevCpuInfo {
let prevCpuInfoSize: size_t = MemoryLayout<integer_t>.stride * Int(self.numPrevCpuInfo)
vm_deallocate(mach_task_self_, vm_address_t(bitPattern: prevCpuInfo), vm_size_t(prevCpuInfoSize))
}
self.prevCpuInfo = self.cpuInfo
self.numPrevCpuInfo = self.numCpuInfo
self.cpuInfo = nil
self.numCpuInfo = 0
} else {
error("host_processor_info(): (String(cString: mach_error_string(result), encoding: String.Encoding.ascii) ?? "unknown error")", log: self.log)
}
let cpuInfo = hostCPULoadInfo()
if cpuInfo == nil {
self.callback(nil)
return
}
let userDiff = Double(cpuInfo!.cpu_ticks.0 - self.previousInfo.cpu_ticks.0)
let sysDiff = Double(cpuInfo!.cpu_ticks.1 - self.previousInfo.cpu_ticks.1)
let idleDiff = Double(cpuInfo!.cpu_ticks.2 - self.previousInfo.cpu_ticks.2)
let niceDiff = Double(cpuInfo!.cpu_ticks.3 - self.previousInfo.cpu_ticks.3)
let totalTicks = sysDiff + userDiff + niceDiff + idleDiff
let system = sysDiff / totalTicks
let user = userDiff / totalTicks
let idle = idleDiff / totalTicks
if !system.isNaN {
self.response.systemLoad = system
}
if !user.isNaN {
self.response.userLoad = user
}
if !idle.isNaN {
self.response.idleLoad = idle
}
self.previousInfo = cpuInfo!
self.response.totalUsage = self.response.systemLoad + self.response.userLoad
self.callback(self.response)
}
电池信息
对于macos
的系统来说,用的比较多的还是属于笔记本系列,这样电池在整个系统来说,占了一个相关重要的作用,电量的显示可以让我们放心的去做工作。如果担心这块软件较为费点,可以参考上面的说明。
获取电池信息:
public override func read() {
let psInfo = IOPSCopyPowerSourcesInfo().takeRetainedValue()
let psList = IOPSCopyPowerSourcesList(psInfo).takeRetainedValue() as [CFTypeRef]
if psList.isEmpty {
return
}
for ps in psList {
if let list = IOPSGetPowerSourceDescription(psInfo, ps).takeUnretainedValue() as? [String: Any] {
self.usage.powerSource = list[kIOPSPowerSourceStateKey] as? String ?? "AC Power"
self.usage.isCharged = list[kIOPSIsChargedKey] as? Bool ?? false
self.usage.isCharging = self.getBoolValue("IsCharging" as CFString) ?? false
self.usage.level = Double(list[kIOPSCurrentCapacityKey] as? Int ?? 0) / 100
if let time = list[kIOPSTimeToEmptyKey] as? Int {
self.usage.timeToEmpty = Int(time)
}
if let time = list[kIOPSTimeToFullChargeKey] as? Int {
self.usage.timeToCharge = Int(time)
}
if self.usage.powerSource == "AC Power" {
self.usage.timeOnACPower = Date()
}
self.usage.cycles = self.getIntValue("CycleCount" as CFString) ?? 0
self.usage.designedCapacity = self.getIntValue("DesignCapacity" as CFString) ?? 1
self.usage.maxCapacity = self.getIntValue((isARM ? "AppleRawMaxCapacity" : "MaxCapacity") as CFString) ?? 1
if !isARM {
self.usage.state = list[kIOPSBatteryHealthKey] as? String
}
self.usage.health = Int((Double(100 * self.usage.maxCapacity) / Double(self.usage.designedCapacity)).rounded(.toNearestOrEven))
self.usage.amperage = self.getIntValue("Amperage" as CFString) ?? 0
self.usage.voltage = self.getVoltage() ?? 0
self.usage.temperature = self.getTemperature() ?? 0
var ACwatts: Int = 0
if let ACDetails = IOPSCopyExternalPowerAdapterDetails() {
if let ACList = ACDetails.takeRetainedValue() as? [String: Any] {
guard let watts = ACList[kIOPSPowerAdapterWattsKey] else {
return
}
ACwatts = Int(watts as! Int)
}
}
self.usage.ACwatts = ACwatts
self.callback(self.usage)
}
}
}
最后
以上就是独特月光为你收集整理的Github每日精选(第22期):macOS 系统监视器stats的全部内容,希望文章能够帮你解决Github每日精选(第22期):macOS 系统监视器stats所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复