9

我该如何检索:

i) 总进程数 ii) 总线程数

注意“总数”是指正在使用的总数, 而不是系统支持的总数。

我特别要求在 OSX 上提供 Objective-C/C 解决方案。

4

3 回答 3

12

您可以使用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 ;
}
于 2012-08-24T20:01:59.107 回答
2

大致遵循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。

最后说明:正如(懒惰地)编写的那样,此代码在失败时会泄漏内存和马赫端口。

于 2012-08-25T08:06:04.160 回答
0

对于 Objective C,您可以使用NSTask进行系统调用sysctl -aw以获取类似

kern.maxproc = xxxx
kern.num_threads: xxxxx
于 2012-08-14T23:36:21.620 回答