为什么你总是感到疲惫?

在Objective-C中获取类似top命令的系统进程信息,可以通过系统级API实现,以下为详细实现方案,适用于macOS开发(iOS因沙盒限制无法获取其他进程信息):


核心实现步骤

获取进程ID列表

- (NSArray *)getAllProcessIDs {
    int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
    size_t length = 0;
    // 获取数据长度
    sysctl(mib, 4, NULL, &length, NULL, 0);
    // 分配内存
    struct kinfo_proc *processList = malloc(length);
    sysctl(mib, 4, processList, &length, NULL, 0);
    int processCount = (int)(length / sizeof(struct kinfo_proc));
    NSMutableArray *pids = [NSMutableArray array];
    for (int i = 0; i < processCount; i++) {
        [pids addObject:@(processList[i].kp_proc.p_pid)];
    }
    free(processList);
    return [pids copy];
}

获取单个进程详细信息

#import <libproc.h>
#import <mach/mach.h>
- (NSDictionary *)processInfoForPID:(pid_t)pid {
    // 1. 获取进程名称
    char name[256];
    proc_name(pid, name, sizeof(name));
    NSString *processName = [NSString stringWithUTF8String:name];
    // 2. 获取CPU使用率(需两次采样计算)
    static NSMutableDictionary *prevTimeDict;
    if (!prevTimeDict) prevTimeDict = [NSMutableDictionary dictionary];
    struct proc_taskinfo taskInfo;
    proc_pidinfo(pid, PROC_PIDTASKINFO, 0, &taskInfo, sizeof(taskInfo));
    double cpuUsage = 0.0;
    if (prevTimeDict[@(pid)]) {
        uint64_t prevTime = [prevTimeDict[@(pid)] unsignedLongLongValue];
        uint64_t timeDiff = taskInfo.pti_total_user + taskInfo.pti_total_system - prevTime;
        cpuUsage = (timeDiff / 10000000.0); // 转换为百分比
    }
    prevTimeDict[@(pid)] = @(taskInfo.pti_total_user + taskInfo.pti_total_system);
    // 3. 获取内存占用
    struct proc_regioninfo regionInfo;
    proc_pidinfo(pid, PROC_PIDREGIONINFO, 0, &regionInfo, sizeof(regionInfo));
    unsigned long memoryUsage = regionInfo.pri_private_resident_size / 1024; // KB
    return @{
        @"pid": @(pid),
        @"name": processName,
        @"cpu": @(cpuUsage),
        @"memory": @(memoryUsage)
    };
}

整合所有进程数据

- (NSArray *)getTopProcesses {
    NSArray *pids = [self getAllProcessIDs];
    NSMutableArray *processes = [NSMutableArray array];
    for (NSNumber *pidNum in pids) {
        pid_t pid = [pidNum intValue];
        NSDictionary *info = [self processInfoForPID:pid];
        if (info) [processes addObject:info];
    }
    // 按CPU使用率排序
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"cpu" ascending:NO];
    return [processes sortedArrayUsingDescriptors:@[sortDescriptor]];
}

关键说明

  1. 权限要求

    • 需要开启com.apple.security.get-task-all权限(在Entitlements文件中)
    • macOS应用需签名并开启沙盒的Allow Debugging权限
  2. 性能优化

    • 避免频繁调用(建议采样间隔≥1秒)
    • 使用缓存存储上次采样时间
    • 过滤pid=0的系统进程
  3. iOS限制

    • iOS只能获取当前应用的信息
    • 使用NSProcessInfo获取当前进程数据:
      double cpu = [NSProcessInfo processInfo].processorLoad;
      long memory = [NSProcessInfo processInfo].physicalMemory / 1024;

输出示例

[
  {"pid": 123, "name": "Xcode", "cpu": 45.2, "memory": 102400},
  {"pid": 456, "name": "Safari", "cpu": 22.1, "memory": 87600},
  ...
]

替代方案(系统命令)

若无需实时控制,可直接调用top命令:

NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:@"/usr/bin/top"];
[task setArguments:@[@"-l", @"1", @"-n", @"10"]]; // 采样1次,前10进程
NSPipe *pipe = [NSPipe pipe];
[task setStandardOutput:pipe];
[task launch];
NSData *data = [[pipe fileHandleForReading] readDataToEndOfFile];
NSString *output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

注意事项

  1. 内存管理:使用free()释放malloc分配的内存
  2. 错误处理:检查sysctl/proc_pidinfo返回值
  3. 实时性:CPU使用率需两次采样计算差值
  4. 沙盒限制:完整功能需关闭App Sandbox

引用说明:本文实现基于Apple官方文档 proc_info(2) 及 sysctl(3) 系统调用。

原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/5061.html

(0)
酷番叔酷番叔
上一篇 2025年6月19日 22:39
下一篇 2025年6月19日 22:54

相关推荐

  • 安全传输数据设备如何保障数据绝对安全?

    在数字化时代,数据已成为企业的核心资产,而安全传输数据设备则是保障数据在流转过程中不被窃取、篡改或损坏的关键基础设施,这些设备通过硬件加密、协议防护、身份认证等技术手段,构建起数据传输的安全屏障,为金融、医疗、政务等关键行业提供了可靠的数据安全保障,安全传输数据设备的核心功能与技术安全传输数据设备的核心在于确保……

    2025年12月7日
    10900
  • ASP页面语法错误如何快速定位解决?

    在开发ASP(Active Server Pages)应用程序时,语法错误是开发者最常遇到的问题之一,这类错误通常源于代码编写不规范、逻辑不清晰或对ASP内置对象和方法的误解,本文将系统梳理ASP页面语法错误的常见类型、排查方法及最佳实践,帮助开发者提升代码质量,ASP语法错误的常见类型ASP语法错误主要分为三……

    2025年12月16日
    12900
  • 重要提示必看?

    仅作参考,不构成任何建议,信息可能存误差或变更,使用风险需自行承担,对据此操作产生的损失,提供方不承担责任。

    2025年8月9日
    14800
  • 埃塞俄比亚商标注册周期一般需多久?

    埃塞俄比亚商标注册周期是企业在规划品牌保护策略时需要重点关注的时间因素,作为非洲的重要经济体,埃塞俄比亚的市场潜力逐渐吸引国际企业的目光,而商标注册作为品牌法律保护的基础,其办理周期的长短直接影响企业的市场进入节奏,本文将从埃塞俄比亚商标注册的基本流程、各阶段耗时、影响因素及优化建议等方面,全面解析商标注册周期……

    2025年12月12日
    12600
  • 如何高效掌握Abaqus命令输入的3种方法?

    CAE图形界面操作(推荐新手)本质:通过可视化界面生成命令,无需手动编码操作流程:Modules菜单 → 选择模块(如Part, Property, Step等) → 使用工具栏功能(如Create Part, Assign Material) → 自动生成后台命令(记录于.jnl日志文件)查看生成命令:菜单栏……

    2025年8月5日
    16400

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-880-8834

在线咨询: QQ交谈

邮件:HI@E.KD.CN

关注微信