どうすれば取得できますか:
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 を呼び出す方がよいでしょう。それらはすでに root に設定されているからです。
最後の注意: (怠惰に) 書かれているように、このコードは失敗時にメモリと Mach ポートの両方をリークします。
Objective C の場合、NSTaskを使用してシステム コールを実行し、次のsysctl -aw
ようなものを取得できます。
kern.maxproc = xxxx
kern.num_threads: xxxxx