检测主线程被使用的时间百分比。

3
我正在尝试检测主线程繁忙的时间百分比,以便在用户使用应用程序时记录此度量。目前,我能找到的最接近的东西是从basic_info中获取user_time, 并参考这里的答案,但如何知道正在使用哪个线程以及是否为主线程?然后,我如何确定该时间在会话期间占应用程序总运行时间的百分比?

这是什么目的?你不能在AppDelegate内部管理吗? - Kamran
2个回答

3

所以我使用以下方法找到了解决方案:

class MainThreadAnalyser {
    typealias SumTotal = (total: Double, elements: Double)

    private var threadPercentages = [Double]()

    private let timeIntervalSeconds: Double

    init(timeIntervalSeconds: Double) {
        self.timeIntervalSeconds = timeIntervalSeconds
        if #available(iOS 10.0, *) {
            self.startCPUMonitoring(timeIntervalSeconds: self.timeIntervalSeconds)
        }
    }

    func getAverageCpuUsage() -> Double? {
        let sumTotal = threadPercentages.reduce((total: 0, elements: 0)) { (sum, item) -> SumTotal in
            var result = sum
            if item > 0 {
                result.total += item
                result.elements += 1
            }

            return result
        }

        return sumTotal.elements > 0 ? sumTotal.total / sumTotal.elements : nil
    }

    @available(iOS 10.0, *)
    private func startCPUMonitoring(timeIntervalSeconds: Double) {
        Timer.scheduledTimer(withTimeInterval: timeIntervalSeconds, repeats: true) { [weak self] _ in
            guard let strongSelf = self else { return }
            if let cpuUsage = strongSelf.cpuUsage() {
                strongSelf.threadPercentages.append(cpuUsage)
            }
        }
    }

    private func cpuUsage() -> Double? {
        var kernReturn: kern_return_t
        var taskInfoCount: mach_msg_type_number_t

        taskInfoCount = mach_msg_type_number_t(TASK_INFO_MAX)
        var tinfo = [integer_t](repeating: 0, count: Int(taskInfoCount))

        kernReturn = task_info(mach_task_self_, task_flavor_t(TASK_BASIC_INFO), &tinfo, &taskInfoCount)
        if kernReturn != KERN_SUCCESS {
            return -1
        }

        var threadArray: thread_act_array_t? = UnsafeMutablePointer(mutating: [thread_act_t]())
        var threadCount: mach_msg_type_number_t = 0
        defer {
            if let threadArray = threadArray {
                vm_deallocate(mach_task_self_, vm_address_t(UnsafePointer(threadArray).pointee), vm_size_t(threadCount))
            }
        }

        kernReturn = task_threads(mach_task_self_, &threadArray, &threadCount)

        if kernReturn != KERN_SUCCESS {
            return -1
        }

        var totalCPU: Double?

        if let threadArray = threadArray {

            for index in 0 ..< Int(threadCount) {
                var threadInfoCount = mach_msg_type_number_t(THREAD_INFO_MAX)
                var thinfo = [integer_t](repeating: 0, count: Int(threadInfoCount))
                kernReturn = thread_info(threadArray[index], thread_flavor_t(THREAD_BASIC_INFO),
                                 &thinfo, &threadInfoCount)
                if kernReturn != KERN_SUCCESS {
                    return -1
                }

                if index == 0 {
                    let cpuUse = thinfo[4]
                    totalCPU = Double(cpuUse/10)

                }
            }
        }

        return totalCPU
    }
}

0

当应用程序在前台运行时,主线程会被持续使用。因此,您可以在applicationDidBecomeActive中安排一个计时器,并在applicationWillResignActive中使其失效,以便在任何时候获取累积的秒数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接