【问题标题】:Number of Running Processes on a Minix system from C code来自 C 代码的 Minix 系统上正在运行的进程数
【发布时间】:2011-11-06 06:08:10
【问题描述】:

所以,一开始这似乎很简单,但是在爬了谷歌和这里之后,答案似乎并没有我最初想的那么简单。

基本上,我正在编辑一个 MINIX 内核,作为我操作系统课程实践的一部分,并且我必须添加一个小函数,当您在信息服务器中按下一个功能键时,它会吐出正在运行的进程的数量。我已经想出了如何集成功能,以便所有其他东西都能正常工作,但对于我的一生,我无法弄清楚如何将系统中运行的当前进程数放入我的 C 代码和变量中打印出来。

首先,我认为会有一个漂亮的系统调用,例如 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() 调用的输出之外,还必须有更好的方法来做到这一点。

再次编辑:上面的代码完全可以从用户程序中运行,但不能从内核函数中运行。有人知道为什么吗?:/

【问题讨论】:

  • 那么你是在编辑内核源代码,还是在尝试编写一个普通的程序?
  • Linux != Minix。 Torvalds 和 Tanenbaum 都会对你非常失望......
  • Minix 不是 linux,它是 unix... Tannenbaum 可能会因为暗示他的内核设计与 Torvald 的设计相似而杀死你。如果您正在阅读 linux 内核指南,您可能会出错。 (如果这是我没听说过的其他 minix,评论无效;-))
  • 是的,是的,你没关系,它是 UNIX,在你们都指出之后我才想起 :) - 在这一点上,很多内核在核心功能方面是相似的对于 Linux 和 Minix,我必须更改的内容可能相似,但我什至还没有真正找到一种 Linux 方法。
  • 您的 fgets() 将在字符串末尾留下一个换行符 ('\n')。如果你不完全控制buffer 的内容,printf(buffer) 通常是不明智的(如果它包含% 字符,你就有麻烦了);使用printf("%s", buffer) 或fputs(buffer, stdout)。

标签: c unix process minix


【解决方案1】:

尝试查看 ps 的作用。查看它的源代码;它知道有多少进程

【讨论】:

  • 它使用proc_data_t 来枚举进程。不确定这是在哪里定义的...
【解决方案2】:

也许您可以向我们展示您为捕获system("ps -ax | wc -l") 的结果而编写的代码,或者您为使用popen 而编写的代码,我们可以帮助您诊断问题。

无论如何,我能想到的计算系统上现有(与正在运行的)进程数的最有效方法是 opendir("/proc") 并计算十进制数字字符串的条目数。系统中的每个进程都将由/proc 的子目录表示,以该进程的十进制进程ID 号命名。

因此,例如,如果您找到“/proc/3432”,那么您就知道存在一个 pid 为“3432”的进程。只需计算您找到的名称为十进制数字的子目录的数量。


假设:
  • 你问的是Linux,而不是MINIX。
  • 您正在编写用户模式程序,而不是修改内核。

【讨论】:

    【解决方案3】:

    看看这个:http://procps.sourceforge.net/

    它有许多做这类事情的小型实用程序的来源。这将是一次很好的学习体验:) 我认为 PS 就在其中,正如 pm100 所指出的那样。

    【讨论】:

      【解决方案4】:

      如果您正在编辑内核,解决此问题的最有效方法是在每次创建进程(即 task_struct 条目)时维护一个计数(并确保每次进程终止时都减少计数)。

      你总是可以使用内置宏循环遍历内核中的进程列表(但它很昂贵,所以你应该尽量避免它):

      struct task_struct *p;
      unsigned int count = 0;
      for_each_process(task) {
          count++;
      }
      

      【讨论】:

      • 我喜欢您对流程列表的后一种想法。我知道它很昂贵,但是对于几乎从未调用过的功能来说,这并不重要。我查看了文件中的其他一些源,它为许多进程引用了一些常量缓冲区,但我仍然不确定我应该如何获取要循环的进程列表。
      • 既然还是 UNIX,就想办法找到初始化任务(PID 0)并从那里迭代(如果没有内置迭代器的话)。
      【解决方案5】:
      struct kinfo kinfo;
      int nr_tasks, nr_procs;
      getsysinfo(PM_PROC_NR, SI_KINFO, &kinfo);
      nr_procs = kinfo.nr_pro;
      

      这将为您提供正在运行的进程数

      【讨论】:

        【解决方案6】:

        所以我一直遇到同样的问题并找到了解决方案。 (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 */
        

        【讨论】:

          【解决方案7】:

          看看这个: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;
          }
          

          【讨论】:

            【解决方案8】:

            我在我的大学有同样的任务,所以如果将来有人需要我会发布我的解决方案。我正在为虚拟机使用 Minix 3.3 和 VMware 播放器。
            在 /usr/src/minix/servers/pm 位置的 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(&amp;kinfo) 可以从您的新系统调用中调用,其作用与上述相同。问题是kinfo.nr_procs 不会返回当前进程的数量,而是可以在操作系统中的最大用户进程数,默认为 256,并且可以在定义 NR_PROCS 的文件中手动更改。另一方面kinfo.nr_tasks将返回操作系统可以容纳的最大内核进程数,默认为5。

            【讨论】:

            • 这会为我打印出数字 38。这似乎很高
            猜你喜欢
            • 2015-05-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-05-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多