RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 636008
Accepted
Andrey
Andrey
Asked:2020-03-06 18:07:49 +0000 UTC2020-03-06 18:07:49 +0000 UTC 2020-03-06 18:07:49 +0000 UTC

计算子树中的进程

  • 772

给定进程的 PID,您需要找出此 PID 为 PPID 的进程的数量。

如何使用 ps 实用程序(或其他一些实用程序)来实现它。

linux
  • 3 3 个回答
  • 10 Views

3 个回答

  • Voted
  1. Best Answer
    Mike
    2020-03-06T18:13:14Z2020-03-06T18:13:14Z
    ps -h --ppid 1 | wc -l
    

    键 ps:-h没有标头(无论它是进程的什么),--ppid使用给定的 ppid 发布进程。ps 的输出是 served wc,它可以计算行数。

    要递归地获取所有孩子的数量,您可以使用 pstree 并做一些魔术:

    pstree -p 1 | grep -oP '\(\d+\)' | tail -n +2 | wc -l
    

    pstree从指定的开始绘制进程树。可惜树太美,不便寄托。密钥-p在树上给出括号中进程的 pid。我们用 grep 选择这些括号。我们跳过第一行tail,因为这是我们开始的过程本身。最后,我们算数。但是如果系统有一个进程只调用括号中的数字(原则上不太可能),则可能会出错

    • 4
  2. avp
    2020-03-07T03:32:04Z2020-03-07T03:32:04Z

    由于标签是 C,它可能对某些人有用,该程序可以为给定进程的整个后代树解决此问题。

    让我们以命令接收的 PPID 对列表、所有进程的 PID 为基础,
    ps -e -o ppid,pid
    并按 PPID 值对其进行排序。因此,每个进程的所有后代都将在附近。

    让我们在这个列表中找到给定进程的所有直接后代(即列表中 PPID 等于给定 PID 的那些对)并依次对每个进程执行相同的搜索(我们将“遍历进程树” ”)。为了实现我们的搜索步骤,我们使用了一个 PID 队列,我们​​将找到的直接后代放在其中。

    结果(给定进程的子进程数)将等于放置在队列中(从队列中移除)的元素数减去给定进程,它初始化队列以进行树遍历。

    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <errno.h>
    
    int
    main (int ac, char *av[])
    {
      pid_t inipid = atoi(av[1] ? : "0");
      if (kill(inipid, 0) && errno == ESRCH)
        exit((puts("No such process"), 1));
    
      // сортируем по ppid, таким образом все потомки одного pid окажутся рядом
      FILE *in = popen("ps -e --no-headers -o ppid,pid | sort -n -k 1", "r");
      if (!in)
        exit((perror("ps ..."), 2));
    
      int ppasize,
        nppa = 0;   // количество пар ppid,pid (всего процессов из ps -e)
      struct pids {
        pid_t ppid, pid;
      } *ppa = (__typeof__(ppa))malloc(sizeof(*ppa) * (ppasize = 100));
      if (!ppa)
        exit((perror("malloc"), 2));
    
      // прочтем отсортированный по ppid набор ppid,pid в ppa[]
      while (fscanf(in, "%d %d", &ppa[nppa].ppid, &ppa[nppa].pid) == 2) 
        if (++nppa == ppasize)
          if (!(ppa = (__typeof__(ppa))realloc(ppa, sizeof(*ppa) * (ppasize *= 2))))
            exit((perror("realloc"), 2));
      pclose(in);
    
      /* 
         Пройдем по дереву потомков inipid и подсчитаем их число.
         Для этого используем очередь.
         Для pid из головы очереди ищем в ppa[] все процессы с таким ppid
         (это непосредственные потомки) и помещаем их в хвост очереди.
         Повторяем, пока в очереди что-то есть.
         Количество элементов выбранных из очереди является ответом (-1 inipid)
      */
      pid_t q[nppa + 1];  // очередь потомков inipid
      int qh = 0, qt = 0, // индексы head и tail очереди
        nchilds = -1;     // наш result
      q[qt++] = inipid;   // инициируем процесс поиска, занеся в очередь inipid
    
      // повторяем, пока очередь не станет пустой
      do {
        nchilds++;
        pid_t pid = q[qh++]; // новый parent
        int  first = 0, last = nppa, mid;
    
        // используем binsearch для поиска первого потомка (ppa[i].ppid == pid)
        while (first < last) {
          mid = first + (last - first) / 2;
          // такое вычисления middle позволяет избегать overflow в общем случае
          if (pid > ppa[mid].ppid)
            first = mid + 1;
          else
            last = mid;
        }
        // переберем всех потомков pid и занесем их в очередь
        // они расположены последовательно, поскольку мы сортировали ppa[] по ppid
        while (first < nppa && pid == ppa[first].ppid)
          q[qt++] = ppa[first++].pid;
    
      } while (qh < qt);
    
      free(ppa);
      return printf("pid %d has %d childs (of %d total pids)\n",
                    inipid, nchilds, nppa) < 0;
    }
    

    PS通过/进行
    类型转换,这样程序也可以由 C++ 编译器翻译。mallocrealloc__typeof__

    • 2
  3. Andrey
    2020-03-06T20:59:22Z2020-03-06T20:59:22Z

    计算进程的所有子进程:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    #define MAX_SIZE 300
    
    int countProc(int pid)
    {
        int count = 0;
        char cmd[MAX_SIZE];
        FILE *fd;   
    
        sprintf(cmd, "ps -o %%p --ppid %d", pid); 
        fd = popen(cmd, "r");
        fscanf(fd, "%*s");
    
        int id; 
        while(fscanf(fd, "%d", &id) != EOF)
        {
            count++;
            count += countProc(id);
        }
    
        pclose(fd);
    
        return count;
    }
    
    int main(int argc, char *argv[])
    {
        if(argc != 2)
        {
            printf("Error!\n");
            return 1;
        }
    
        int pid = atoi(argv[1]);
    
        int count = countProc(pid) + 1; 
    
        printf("%d\n", count);
    
        return 0;
    }
    
    • 1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5