How can I retrieve:
i) Number of total processes ii) Number of total threads
Note by "total" I mean the total number in use not the total supported by the system.
I am specifically asking for an Objective-C/C solution on OSX.
If the Windows key is not available on your keyboard, using your mouse, go to the Windows icon located on the bottom-left corner of your screen, right-click, and choose System. Look up the processor's name and number in the Processor information.
Method 1: Use the set command To use the set command to determine the processor type, follow these steps: Click Start, click Run, type cmd in the Open box, and then press ENTER. At the command prompt, type set, and then press ENTER. Note the string that is displayed next to PROCESSOR_IDENTIFIER.
If you're wondering how to check your clock speed, click the Start menu (or click the Windows* key) and type “System Information.” Your CPU's model name and clock speed will be listed under “Processor”.
You can use top
and scrape what you're looking for, but I was curious so I dug a bit deeper and found /usr/include/libproc.h
, and wrote some code:
#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 ;
}
Following, roughly, the source code for top(1), this works when run as 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;
}
Obtaining information about all processes on the system requires elevated privileges, so if you need to do this as an unprivileged user, calling top or ps via NSTask is probably a better option, as they're already setuid root.
Final note: as (lazily) written, this code leaks both memory and Mach ports on failure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With