【问题标题】:Detect percentage of time main thread is used检测使用主线程的时间百分比
【发布时间】:2019-07-12 16:10:04
【问题描述】:

我正在尝试检测主线程忙碌的时间百分比,以便在用户使用应用程序时记录此指标。目前,我能找到的最接近的东西是来自basic_infouser_time 在答案here 的帮助下,但我怎么知道正在使用哪个线程以及它是否是主线程?那么从这里我如何知道该会话的应用程序总运行时间占该时间的百分比?

【问题讨论】:

  • 目的是什么?你不能在AppDelegate里面管理这个吗?

标签: ios objective-c swift multithreading pthreads


【解决方案1】:

所以我设法使用以下方法解决了这个问题:

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
    }
}

【讨论】:

    【解决方案2】:

    当应用程序在前台时,主线程一直在使用。 因此,您可以在applicationDidBecomeActive 中安排一个计时器,并在applicationWillResignActive 中使其无效,并随时获取累积的秒数。

    【讨论】:

      猜你喜欢
      • 2015-10-31
      • 2016-11-21
      • 2018-11-27
      • 2011-12-14
      • 1970-01-01
      • 1970-01-01
      • 2020-11-26
      • 1970-01-01
      • 2019-07-16
      相关资源
      最近更新 更多