Определять информацию о процессе программно в Darwin / OSX
-
03-07-2019 - |
Вопрос
У меня есть класс со следующими функциями-членами:
/// 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;
Обязанностью этого класса является возврат информации о процессе вызывающего абонента.Размер физической памяти можно легко определить с помощью вызова sysctl, а pid тривиален, но остальные вызовы ускользнули от меня, кроме вызова popen в ps или top и синтаксического анализа выходных данных, что неприемлемо.Мы были бы очень признательны за любую помощь.
Требования:
Компилируется на g ++ 4.0
Нет obj-c
OSX 10.5
Решение
Информация о процессе поступает из pidinfo
:
cristi:~ diciu$ grep proc_pidinfo /usr/include/libproc.h
int proc_pidinfo(int pid, int flavor, uint64_t arg, void *buffer, int buffersize);
загрузка процессора происходит из 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
Для получения более подробной информации ознакомьтесь с источниками для top
и lsof
, они имеют открытый исходный код (вам необходимо зарегистрироваться в качестве разработчика Apple, но это бесплатно).:
https://opensource.apple.com/source/top/top-111.20.1/libtop.c.auto.html
Последующее редактирование: Все эти интерфейсы зависят от версии, поэтому вам необходимо учитывать это при написании производственного кода (libproc.h).:
/*
* This header file contains private interfaces to obtain process information.
* These interfaces are subject to change in future releases.
*/
Другие советы
Поскольку вы говорите "нет Objective-C", мы исключим большинство фреймворков macOS.
Вы можете получить процессорное время с помощью getrusage(), которая выдает общее количество пользовательского и системного процессорного времени, затрачиваемого на ваш процесс.Чтобы получить процент процессора, вам нужно будет делать моментальный снимок значений getrusage один раз в секунду (или каким бы детализированным вы ни хотели быть).
#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);
В структуре getrusage есть поле RSS, но, похоже, в macOS X 10.5 оно всегда равно нулю. Майкл Найт несколько лет назад написал сообщение в блоге о том, как определить RSS.
Я думаю, что большинство из этих значений доступны в Mach API, но прошло много времени с тех пор, как я там копался.В качестве альтернативы, вы могли бы просто взглянуть на исходный код команд "ps" или "top" и посмотреть, как они это делают.
Вы можете использовать приведенный ниже код для получения информации о процессе в 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 содержит всю информацию о процессе.такую как идентификатор процесса (pid), группа процесса, статус процесса и т.д.
Большую часть этой информации можно получить из GetProcessInformation() Получить обработанную информацию().
Кстати, зачем нужны виртуальные методы для функций, которые возвращают информацию по всему процессу?
Это УГЛЕРОД только, и не будет работать с cocoa