Количество запущенных процессов в системе Minix из кода C
Итак, сначала это казалось простым, но после сканирования Google и здесь, ответ не кажется таким простым, как я думал вначале.
По сути, я редактирую ядро MINIX как часть практического курса по моим операционным системам, и мне нужно добавить небольшую функцию, которая выплевывает количество запущенных процессов при нажатии функциональной клавиши на информационном сервере. Я выяснил, как интегрировать функциональность, чтобы все остальные вещи работали, но я не могу понять, как получить текущее число процессов, работающих в системе, в мой код C и в переменную для распечатывать.
Сначала я подумал, что будет отличный Syscall, такой как SYS_NUMPROCS, или что-то, что вернет значение, но не повезло. Затем я попытался скопировать вывод из системы ("ps -ax | wc -l") в файл, и файл не был создан. Я попытался использовать popen(), и мне тоже не повезло - даже при простом считывании "ls" в буфер, он просто бомбит код и "зависает" во время выполнения кода, поэтому вывода нет.
Так что теперь я действительно в замешательстве, и любая помощь была бы супер, потому что на данный момент я исчерпал все очевидные варианты.
Единственные две вещи, о которых я могу думать сейчас, это цикл, подсчитывающий все процессы, но сначала вы должны попасть в список процессов системы, и я слышал неясные слова о /proc/ как о директории, но у меня нет ' Понять, как получить доступ / пройти через это или как это связано с получением количества процессов в первую очередь.
Спасибо за стек (смеется), ребята:)
Кроме того, я не включил код явно, потому что я ничего не написал, кроме базового printf'ing для косметического вывода, потому что ничего из того, что я пробовал, не доставило мне радости:/
Примечания по редактированию: Ребята, это редактирование ядра - я пишу функцию для печати информации в системном файле C, затем перекомпилирую ядро и перезагружаю систему для тестирования. Это ядро UNIX (MINIX), а не ядро Linux, и это не программа пользовательского режима.
Мой код для popen(), как некоторые из вас просили, выглядит следующим образом:
public void cos_dmp(){
char buffer[512];
FILE * f;
f = popen("ps -ax | wc -l","r");
fgets(buffer, sizeof(buffer),f);
//buffer should now contain result of popen()
printf(buffer);
}
Это немного взломанная версия из того, что я помню, и она очень проста и показывает вам, ребята, это то, что я пытался сделать. Опять же, однако, должен быть лучший способ сделать это, кроме того, чтобы по существу вызывать выходные данные вызова system().
Отредактируйте снова: приведенный выше код прекрасно работает из пользовательской программы, но не работает из функции ядра. У кого-нибудь есть идеи почему?
8 ответов
struct kinfo kinfo;
int nr_tasks, nr_procs;
getsysinfo(PM_PROC_NR, SI_KINFO, &kinfo);
nr_procs = kinfo.nr_pro;
Это даст вам количество запущенных процессов.
Возможно, вы могли бы показать нам код, который вы написали для захвата результата system("ps -ax | wc -l")
или код, который вы написали для использования popen
и мы могли бы помочь вам диагностировать проблему с ним.
Несмотря на это, самый эффективный способ подсчета количества существующих (не совпадающих с запущенными) процессов в системе - это opendir("/proc")
и подсчитать количество записей, которые являются строками десятичных цифр. Каждый процесс в системе будет представлен подкаталогом / proc, названным в честь десятичного идентификатора процесса этого процесса.
Так, если вы найдете, например, "/proc/3432", то вы знаете, что существует процесс с pid "3432". Просто посчитайте количество найденных подкаталогов, имена которых являются десятичными числами.
Предположения:
Попробуйте посмотреть, что делает PS. Посмотрите на его исходный код; он знает, сколько существует процессов
У меня было такое же назначение в моем университете, поэтому я опубликую свое решение, если кому-то оно понадобится в будущем. Я использую Minix 3.3 и VMware Player для виртуальных машин.
В сервере pm по адресу /usr/src/minix/servers/pm находится файл glo.h, содержащий различные глобальные переменные, используемые сервером pm. К счастью, в этом файле есть одна переменная с именем procs_in_use, определенная как EXTERN int procs_in_use;
Так просто printf("%d\n",procs_in_use);
из системного вызова покажет количество запущенных текущих процессов. Вы можете проверить это, добавив fork()
функция в вашей программе пространства пользователя в середине цикла.
Еще одно упоминание: первый ответ, который говорит
struct kinfo kinfo;
int nr_tasks, nr_procs;
getsysinfo(PM_PROC_NR, SI_KINFO, &kinfo);
nr_procs = kinfo.nr_procs;
не сработало для меня. SI_KINFO
больше не существует, поэтому вы должны использовать SI_PROC_TABLE
, Также могут быть проблемы с разрешениями, поэтому вы не сможете вызывать эту функцию из своего обычного системного вызова. Есть альтернативная функция sys_getkinfo(&kinfo)
это может быть вызвано из вашего нового системного вызова, и это будет делать то же самое, что и выше. Проблема в kinfo.nr_procs
не будет возвращать число текущих процессов, но число максимальных пользовательских процессов, которое может быть в операционной системе, которое по умолчанию равно 256 и может быть изменено вручную в файле, где определено NR_PROCS. С другой стороны kinfo.nr_tasks
вернет максимальное количество процессов ядра, которое может быть выполнено операционной системой, которое по умолчанию равно 5.
У меня возникла та же проблема, и я нашел решение. (MINIX 3.1) в методе для подсчета процессов используйте этот код: (это ANSI C)
Он просто проходит через таблицу процессов и считает количество процессов.
Я знаю, что это старая тема, но она может помочь кому-то в будущем.
#include "../pm/mproc.h"
/* inside function */
struct mproc *mp;
int i, n=0;
printf("Number of running processes:\n");
getsysinfo(PM_PROC_NR, SI_PROC_TAB, mproc);
for (i = 0; i<NR_PROCS; i++) {
mp = &mprocs[i];
if (mp->mp_pid == 0 && i != PM_PROCS_NR) continue;
n++;
}
printf("%d", n);
/* function end */
Если вы редактируете ядро, самый эффективный способ решить эту проблему - поддерживать счетчик каждый раз, когда создается процесс (т.е. запись task_struct) (и обязательно уменьшать счетчик каждый раз, когда процесс завершается).
Вы всегда можете просмотреть список процессов в ядре, используя встроенный макрос (но он дорогой, поэтому вам следует избегать его):
struct task_struct *p;
unsigned int count = 0;
for_each_process(task) {
count++;
}
Проверьте это: http://procps.sourceforge.net/
Это источник множества небольших утилит, которые делают подобные вещи. Это будет хороший опыт обучения:), и я думаю, что PS там, как отметил pm100.
Проверьте это: http://sourceforge.net/p/readproc/code/ci/master/tree/
#include"read_proc.h"
int main(void)
{
struct Root * root=read_proc();
printf("%lu\n",root->len);
return 0;
}