我该如何检索:
i) 总进程数 ii) 总线程数
注意“总数”是指正在使用的总数, 而不是系统支持的总数。
我特别要求在 OSX 上提供 Objective-C/C 解决方案。
我该如何检索:
i) 总进程数 ii) 总线程数
注意“总数”是指正在使用的总数, 而不是系统支持的总数。
我特别要求在 OSX 上提供 Objective-C/C 解决方案。
您可以使用top
和抓取您要查找的内容,但我很好奇,所以我深入挖掘并找到/usr/include/libproc.h
了,并编写了一些代码:
#import <libproc.h>
#import <stdlib.h>
#import <stdio.h>
int main( int argc, const char * argv[])
{
pid_t * pids = calloc(0x1000, 1);
int count = proc_listallpids(pids, 0x1000);
printf("count=%u\n", count) ;
for( int index=0; index < count; ++index)
{
pid_t pid = pids[ index ] ;
struct proc_taskinfo taskInfo ;
/*int result*/ proc_pidinfo( pid, PROC_PIDTASKINFO, 0, & taskInfo, sizeof( taskInfo ) ) ;
// fields of taskInfo:
// uint64_t pti_virtual_size; /* virtual memory size (bytes) */
// uint64_t pti_resident_size; /* resident memory size (bytes) */
// uint64_t pti_total_user; /* total time */
// uint64_t pti_total_system;
// uint64_t pti_threads_user; /* existing threads only */
// uint64_t pti_threads_system;
// int32_t pti_policy; /* default policy for new threads */
// int32_t pti_faults; /* number of page faults */
// int32_t pti_pageins; /* number of actual pageins */
// int32_t pti_cow_faults; /* number of copy-on-write faults */
// int32_t pti_messages_sent; /* number of messages sent */
// int32_t pti_messages_received; /* number of messages received */
// int32_t pti_syscalls_mach; /* number of mach system calls */
// int32_t pti_syscalls_unix; /* number of unix system calls */
// int32_t pti_csw; /* number of context switches */
// int32_t pti_threadnum; /* number of threads in the task */
// int32_t pti_numrunning; /* number of running threads */
// int32_t pti_priority; /* task priority*/
printf("PID %u:\n", pid);
printf("\t%20s\t%u\n", "number of threads", taskInfo.pti_threadnum) ;
printf("\t%20s\t%u\n", "number running threads", taskInfo.pti_numrunning) ;
printf("\n") ;
}
return EXIT_SUCCESS ;
}
大致遵循top(1)的源代码,这在以 root 身份运行时有效:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <mach/mach.h>
#include <mach/mach_error.h>
#include <mach/mach_vm.h>
#include <mach/task.h>
kern_return_t get_process_thread_count(long *process_count, long *thread_count) {
kern_return_t kr;
processor_set_name_array_t psets;
processor_set_t pset;
task_array_t tasks;
mach_msg_type_number_t i, j, k, iCount, jCount, kCount;
long process_accumulator = 0, thread_accumulator = 0;
mach_port_t host_self = mach_host_self();
mach_port_t task_self = mach_task_self();
thread_act_array_t threads;
int pid;
if ((kr = host_processor_sets(host_self, &psets, &iCount))) return kr;
for (i = 0; i < iCount; ++i) {
if ((kr = host_processor_set_priv(host_self, psets[i], &pset))) return kr;
if ((kr = processor_set_tasks(pset, &tasks, &jCount))) return kr;
for (j = 0; j < jCount; ++j) {
if ((kr = pid_for_task(tasks[j], &pid))) return kr;
if (pid != 0) {
/* then the Mach task maps to a BSD process, so */
++process_accumulator;
if ((kr = task_threads(tasks[j], &threads, &kCount))) return kr;
thread_accumulator += kCount;
for (k = 0; k < kCount; ++k) {
if ((kr = mach_port_deallocate(task_self, threads[k]))) return kr;
}
if ((kr = mach_vm_deallocate(task_self,
(mach_vm_address_t)(uintptr_t)threads,
kCount * sizeof(*threads)))) return kr;
}
if ((kr = mach_port_deallocate(task_self, tasks[j]))) return kr;
}
if ((kr = mach_vm_deallocate(task_self,
(mach_vm_address_t)(uintptr_t)tasks,
kCount * sizeof(*tasks)))) return kr;
if ((kr = mach_port_deallocate(task_self, psets[j]))) return kr;
}
if ((kr = mach_vm_deallocate(task_self,
(vm_address_t)psets,
iCount * sizeof(*psets)))) return kr;
*process_count = process_accumulator;
*thread_count = thread_accumulator;
return KERN_SUCCESS;
}
int main(int argc, char* argv[]) {
long process_count, thread_count;
kern_return_t r;
if ((r = get_process_thread_count(&process_count, &thread_count))) {
mach_error("get_process_thread_count error: ", r);
return 1;
};
printf("%ld processes, %ld threads\n", process_count, thread_count);
return 0;
}
获取有关系统上所有进程的信息需要提升权限,因此如果您需要以非特权用户的身份执行此操作,通过 NSTask 调用 top 或 ps 可能是更好的选择,因为它们已经是 setuid root。
最后说明:正如(懒惰地)编写的那样,此代码在失败时会泄漏内存和马赫端口。
对于 Objective C,您可以使用NSTask进行系统调用sysctl -aw
以获取类似
kern.maxproc = xxxx
kern.num_threads: xxxxx