mac 获得进程信息的方法
NSProcessInfo可以获得当前进程的信息。获得所有活动进程信息可以尝试使用下面的方法。
进程的信息可以通过ps命令得到也可以通过sysctl方法得到。 但是我总是不能获取进程的流量信息,关于这一点很纠结,现在的想法就是如果能够获取进程的网络端口,然后对端口进行监听,统计其流量,但是如何能够获取进程的网络端口? 在linux中可以通过netstat命令来查询进程和其对应的端口,但是在macos中netstat命令和linux中不同,并不能实现这一功能(我没找到,但愿是能够的)。 由于本人学习objective-c不久,不知道是否有这样的api,如果你有什么好的方法可以和我联系。 以下是两种方法的代码:
- (void)processListWithPS { _procList = [[NSMutableArray alloc] init]; FILE *fp = popen("ps -eo start,user,pid,pcpu,vsz,rss,etime,utime,stime,msgsnd,msgrcv", "r"); if (fp) { char line[4096] = {0}; int row = 0; while (line == fgets(line, 4096, fp)) { row++; if (row > 1) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; char start[20]; //进程开始时间 char user[50]; //拥有进程用户名 char pid[10]; //进程id char cpu[10]; //进程占用cpu率 char vsz[10]; //vss,虚拟内存 char rss[10]; //rss,物理内存 char etime[20]; //进程持续时间 char utime[20]; //用户占用进程时间 char stime[20]; //系统占用进程时间 sscanf(line, "%s %s %s %s %s %s %s %s %s", start, user, pid, cpu, vsz, rss, etime, utime, stime); NSString *procStart = [NSString stringWithFormat:@"%s", start]; NSString *procUser = [NSString stringWithFormat:@"%s", user]; NSString *procPid = [NSString stringWithFormat:@"%s", pid]; NSString *procCpu = [NSString stringWithFormat:@"%s", cpu]; NSString *procVss = [NSString stringWithFormat:@"%s", vsz]; NSString *procRss = [NSString stringWithFormat:@"%s", rss]; NSString *procETime = [NSString stringWithFormat:@"%s", etime]; NSString *procUtime = [NSString stringWithFormat:@"%s", utime]; NSString *procStime = [NSString stringWithFormat:@"%s", stime]; ProcessInfo *proc = [[ProcessInfo alloc] init]; proc.startTime = procStart; proc.user = procUser; proc.procID = procPid; proc.cpuRate = [procCpu floatValue]; proc.vss = [procVss integerValue]; proc.rss = [procRss integerValue]; proc.usedTime = procETime; proc.utime = procUtime; proc.stime = procStime; proc.upFlow = [procMsgsnd integerValue]; proc.downFlow = [procMsgrcv integerValue]; [_procList addObject:proc]; [pool release]; } } pclose(fp); } }
//返回所有正在运行的进程的 id,name,占用cpu,运行时间 //使用函数int sysctl(int *, u_int, void *, size_t *, void *, size_t)
- (NSArray *)runningProcesses { //指定名字参数,按照顺序第一个元素指定本请求定向到内核的哪个子系统,第二个及其后元素依次细化指定该系统的某个部分。 //CTL_KERN,KERN_PROC,KERN_PROC_ALL 正在运行的所有进程 int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL ,0}; size_t miblen = 4; //值-结果参数:函数被调用时,size指向的值指定该缓冲区的大小;函数返回时,该值给出内核存放在该缓冲区中的数据量 //如果这个缓冲不够大,函数就返回ENOMEM错误 size_t size; //返回0,成功;返回-1,失败 int st = sysctl(mib, miblen, NULL, &size, NULL, 0); struct kinfo_proc * process = NULL; struct kinfo_proc * newprocess = NULL; do { size += size / 10; newprocess = realloc(process, size); if (!newprocess) { if (process) { free(process); process = NULL; } return nil; } process = newprocess; st = sysctl(mib, miblen, process, &size, NULL, 0); } while (st == -1 && errno == ENOMEM); if (st == 0) { if (size % sizeof(struct kinfo_proc) == 0) { int nprocess = size / sizeof(struct kinfo_proc); if (nprocess) { NSMutableArray * array = [[NSMutableArray alloc] init]; for (int i = nprocess - 1; i >= 0; i--) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString * processID = [[NSString alloc] initWithFormat:@"%d", process[i].kp_proc.p_pid]; NSString * processName = [[NSString alloc] initWithFormat:@"%s", process[i].kp_proc.p_comm]; NSString * proc_CPU = [[NSString alloc] initWithFormat:@"%d", process[i].kp_proc.p_estcpu]; double t = [[NSDate date] timeIntervalSince1970] - process[i].kp_proc.p_un.__p_starttime.tv_sec; NSString * proc_useTiem = [[NSString alloc] initWithFormat:@"%f",t]; //NSLog(@"process.kp_proc.p_stat = %c",process.kp_proc.p_stat); NSMutableDictionary *dic = [[NSMutableDictionary alloc] init]; [dic setValue:processID forKey:@"ProcessID"]; [dic setValue:processName forKey:@"ProcessName"]; [dic setValue:proc_CPU forKey:@"ProcessCPU"]; [dic setValue:proc_useTiem forKey:@"ProcessUseTime"]; [processID release]; [processName release]; [proc_CPU release]; [proc_useTiem release]; [array addObject:dic]; [dic release]; [pool release]; } free(process); process = NULL; //NSLog(@"array = %@",array); return array; } } } return nil; }