我不是一个swift开发人员。我需要这个swift代码来按需获取当前的CPU利用率百分比。也就是说,每当我查询它时,我都应该获取当前的阅读。我需要从node.js进程运行这个脚本。它基本上就像从终端运行脚本一样。下面是我从另一个SO线程中找到的脚本,它似乎可以正常工作。
import Foundation
// CPU usage credit VenoMKO: https://stackoverflow.com/a/6795612/1033581
class MyCpuUsage {
var cpuInfo: processor_info_array_t!
var prevCpuInfo: processor_info_array_t?
var numCpuInfo: mach_msg_type_number_t = 0
var numPrevCpuInfo: mach_msg_type_number_t = 0
var numCPUs: uint = 0
var updateTimer: Timer!
let CPUUsageLock: NSLock = NSLock()
init() {
let mibKeys: [Int32] = [ CTL_HW, HW_NCPU ]
// sysctl Swift usage credit Matt Gallagher: https://github.com/mattgallagher/CwlUtils/blob/master/Sources/CwlUtils/CwlSysctl.swift
mibKeys.withUnsafeBufferPointer() { mib in
var sizeOfNumCPUs: size_t = MemoryLayout<uint>.size
let status = sysctl(processor_info_array_t(mutating: mib.baseAddress), 2, &numCPUs, &sizeOfNumCPUs, nil, 0)
if status != 0 {
numCPUs = 1
}
updateTimer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(updateInfo), userInfo: nil, repeats: true)
}
}
@objc func updateInfo(_ timer: Timer) {
var totalInUse: Int32 = 0
var totalTotal: Int32 = 0
var numCPUsU: natural_t = 0
let err: kern_return_t = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numCPUsU, &cpuInfo, &numCpuInfo);
if err == KERN_SUCCESS {
CPUUsageLock.lock()
for i in 0 ..< Int32(numCPUs) {
var inUse: Int32
var total: Int32
if let prevCpuInfo = prevCpuInfo {
inUse = cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_USER)]
- prevCpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_USER)]
+ cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_SYSTEM)]
- prevCpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_SYSTEM)]
+ cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_NICE)]
- prevCpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_NICE)]
total = inUse + (cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_IDLE)]
- prevCpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_IDLE)])
} else {
inUse = cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_USER)]
+ cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_SYSTEM)]
+ cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_NICE)]
total = inUse + cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_IDLE)]
}
totalInUse += inUse
totalTotal += total
}
CPUUsageLock.unlock()
if let prevCpuInfo = prevCpuInfo {
// vm_deallocate Swift usage credit rsfinn: https://stackoverflow.com/a/48630296/1033581
let prevCpuInfoSize: size_t = MemoryLayout<integer_t>.stride * Int(numPrevCpuInfo)
vm_deallocate(mach_task_self_, vm_address_t(bitPattern: prevCpuInfo), vm_size_t(prevCpuInfoSize))
}
prevCpuInfo = cpuInfo
numPrevCpuInfo = numCpuInfo
cpuInfo = nil
numCpuInfo = 0
let totalUsagePercentage = Float(totalInUse) / Float(totalTotal) * 100
print(String(format: "Total CPU Usage: %.2f%%", totalUsagePercentage))
} else {
print("Error!")
}
}
}
let cpuMonitor = MyCpuUsage()
RunLoop.current.run()
字符串
正如你所看到的,这个脚本使用了Timer,并在控制台上每3秒打印一次当前百分比。由于我只想按需打印一次结果,这里是我所做的修改。只是删除了计时器,或者我想我做了。
import Foundation
class MyCpuUsage {
var cpuInfo: processor_info_array_t!
var prevCpuInfo: processor_info_array_t?
var numCpuInfo: mach_msg_type_number_t = 0
var numPrevCpuInfo: mach_msg_type_number_t = 0
var numCPUs: uint = 0
let CPUUsageLock: NSLock = NSLock()
init() {
let mibKeys: [Int32] = [ CTL_HW, HW_NCPU ]
mibKeys.withUnsafeBufferPointer() { mib in
var sizeOfNumCPUs: size_t = MemoryLayout<uint>.size
let status = sysctl(processor_info_array_t(mutating: mib.baseAddress), 2, &numCPUs, &sizeOfNumCPUs, nil, 0)
if status != 0 {
numCPUs = 1
}
// Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(updateInfo), userInfo: nil, repeats: true)
// calling the updateInfo() func to print one time result
updateInfo()
}
}
// Removed exposure to objective-c and the unused parameter "timer"
// @objc func updateInfo(_ timer: Timer) {
func updateInfo() {
// I have added these two variables to calculate sum of all cores
var totalInUse: Int32 = 0
var totalTotal: Int32 = 0
var numCPUsU: natural_t = 0
let err: kern_return_t = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numCPUsU, &cpuInfo, &numCpuInfo);
if err == KERN_SUCCESS {
CPUUsageLock.lock()
for i in 0 ..< Int32(numCPUs) {
var inUse: Int32
var total: Int32
if let prevCpuInfo = prevCpuInfo {
inUse = cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_USER)]
- prevCpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_USER)]
+ cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_SYSTEM)]
- prevCpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_SYSTEM)]
+ cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_NICE)]
- prevCpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_NICE)]
total = inUse + (cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_IDLE)]
- prevCpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_IDLE)])
} else {
inUse = cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_USER)]
+ cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_SYSTEM)]
+ cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_NICE)]
total = inUse + cpuInfo[Int(CPU_STATE_MAX * i + CPU_STATE_IDLE)]
}
// print(String(format: "Core: %u Usage: %f", i, Float(inUse) / Float(total)))
// Assigning totals here
totalInUse += inUse
totalTotal += total
}
CPUUsageLock.unlock()
if let prevCpuInfo = prevCpuInfo {
let prevCpuInfoSize: size_t = MemoryLayout<integer_t>.stride * Int(numPrevCpuInfo)
vm_deallocate(mach_task_self_, vm_address_t(bitPattern: prevCpuInfo), vm_size_t(prevCpuInfoSize))
}
prevCpuInfo = cpuInfo
numPrevCpuInfo = numCpuInfo
cpuInfo = nil
numCpuInfo = 0
let totalUsagePercentage = Float(totalInUse) / Float(totalTotal) * 100
// This is where I print sum of all cores percentage.
print(String(format: "Total CPU Usage: %.2f%%", totalUsagePercentage))
} else {
print("Error!")
}
}
}
let cpuMonitor = MyCpuUsage()
型
我的修改版本的问题是,它似乎在每次调用时打印的百分比与从终端第一次调用时相同。不仅控制台上的打印值保持不变,而且我还尝试运行进程以增加CPU使用率,并通过Activity Monitor确认,但此脚本仍然显示相同的值。任何帮助都将不胜感激。
这是终端的截图。
的数据
的
1条答案
按热度按时间wh6knrhe1#
原始程式码(in 2011)中的公式依赖于两次
host_processor_info
呼叫之间的用法差异。因此,若要让您的想法在没有计时器的情况下运作,您仍然需要至少两次updateInfo()
呼叫。例如,您可以尝试在两者之间使用sleep(1)
秒。程式码已加上注解。
在SwiftPlayground进行测试。
字符串
为了记录在案,Anya在2013年的similar ObjC answer中也记录了在两次调用之间等待1秒的想法:
然后我们取两个样本(样本之间间隔1秒)
型