Determine Process Info Programmatically in Darwin/OSX

20,922

Solution 1

Process info comes from pidinfo:

cristi:~ diciu$ grep proc_pidinfo /usr/include/libproc.h

int proc_pidinfo(int pid, int flavor, uint64_t arg,  void *buffer, int buffersize);

cpu load comes from host_statistics:

cristi:~ diciu$ grep -r host_statistics /usr/include/

/usr/include/mach/host_info.h:/* host_statistics() */

/usr/include/mach/mach_host.defs:routine host_statistics(

/usr/include/mach/mach_host.h:/* Routine host_statistics */

/usr/include/mach/mach_host.h:kern_return_t host_statistics

For more details, check out sources for top and lsof, they are open source (you need to register as an Apple developer but that's free of charge):

https://opensource.apple.com/source/top/top-111.20.1/libtop.c.auto.html

Later edit: All these interfaces are version specific, so you need to take that into account when writing production code (libproc.h):

/*
 * This header file contains private interfaces to obtain process information.
 * These interfaces are subject to change in future releases.
 */

Solution 2

Since you say no Objective-C we'll rule out most of the MacOS frameworks.

You can get CPU time using getrusage(), which gives the total amount of User and System CPU time charged to your process. To get a CPU percentage you'd need to snapshot the getrusage values once per second (or however granular you want to be).

#include <sys/resource.h>

struct rusage r_usage;

if (getrusage(RUSAGE_SELF, &r_usage)) {
    /* ... error handling ... */
}

printf("Total User CPU = %ld.%ld\n",
        r_usage.ru_utime.tv_sec,
        r_usage.ru_utime.tv_usec);
printf("Total System CPU = %ld.%ld\n",
        r_usage.ru_stime.tv_sec,
        r_usage.ru_stime.tv_usec);

There is an RSS field in the getrusage structure, but is appears to always be zero in MacOS X 10.5. Michael Knight wrote a blog post several years ago about how to determine the RSS.

Solution 3

I think most of these values are available in the Mach API, but it's been a while since I've poked around in there. Alternatively, you could just look at the source code for the "ps" or "top" commands, and see how they do it.

Solution 4

You can use below code for process info in mac OS:

void IsInBSDProcessList(char *name)    { 
  assert( name != NULL); 
  kinfo_proc *result; 
  size_t count = 0; 
  result = (kinfo_proc *)malloc(sizeof(kinfo_proc)); 
  if(GetBSDProcessList(&result,&count) == 0) { 
    for (int i = 0; i < count; i++) { 
      kinfo_proc *proc = NULL; 
      proc = &result[i]; 
      }
  } 
  free(result);
}

kinfo_proc struct contains all the information about a process.such as Process identifier (pid), process group, process status and etc.

Share:
20,922
little_monster
Author by

little_monster

Updated on March 06, 2020

Comments

  • little_monster
    little_monster about 4 years

    I have a class with the following member functions:

    
    /// caller pid
    virtual pid_t Pid() const = 0; 
    
    /// physical memory size in KB
    virtual uint64_t Size() const = 0;  
    
    /// resident memory for this process
    virtual uint64_t Rss() const = 0; 
    
    /// cpu used by this process
    virtual double PercentCpu() const = 0; 
    
    /// memory used by this process
    virtual double PercentMemory() const = 0; 
    
    /// number of threads in this process
    virtual int32_t Lwps() const = 0; 
    
    

    This class' duty is to return process information about caller. Physical memory size can easily determined by a sysctl call, and pid is trivial, but the remaining calls have eluded me, aside from invoking a popen on ps or top and parsing the output - which isn't acceptable. Any help would be greatly appreciated.

    Requirements:
    Compiles on g++ 4.0
    No obj-c
    OSX 10.5