6

如何快速统计指定进程的个数

 3 years ago
source link: https://www.lujun9972.win/blog/2018/12/03/%E5%A6%82%E4%BD%95%E5%BF%AB%E9%80%9F%E7%BB%9F%E8%AE%A1%E6%8C%87%E5%AE%9A%E8%BF%9B%E7%A8%8B%E7%9A%84%E4%B8%AA%E6%95%B0/index.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

如何快速统计指定进程的个数

最近某个系统由于处理来帐报文缓慢而导致被上级部门通报。 经过排查发现系统中有一段代码用来统计处理来帐的进程数,若进程数大于某个阀值则开始限流,等待一段时间后再开始接受来帐报文。

而比较讽刺的是,统计进程数的这段代码居然是在C语言中通过 system 来执行外部shell命令实现的。 由于执行shell命令耗时太过严重,实际上这个阀值永远也不可能达到。

一个比较快速的统计进程数量的方法是直接在C语言中遍历 /proc/ 目录中各个 进程号 目录下的 exe 文件,看它是否是统计进程的软链接。

下面是这两种方法耗时的比较:

  1. 通过执行shell命令来统计

    #include <stdlib.h>
    #include <stdio.h>
    #include <sys/time.h>
    
    int64_t getCurrentTime()
    {
      struct timeval tv;
      gettimeofday(&tv,NULL);
      return tv.tv_sec * 1000 + tv.tv_usec / 1000;
    }
    
    int main()
    {
      int64_t start = getCurrentTime();
      system("ps -ef|grep firefox|grep -v grep|wc -l");
      int64_t end = getCurrentTime();
      printf("耗时:%ld\n",(end-start));
      return 0;
    }
    
    
    6
    耗时:19
    
  2. 通过遍历 /proc 目录的方法来统计

    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <dirent.h>
    
    int64_t getCurrentTime()
    {
      struct timeval tv;
      gettimeofday(&tv,NULL);
      return tv.tv_sec * 1000 + tv.tv_usec / 1000;
    }
    
    int main()
    {
      char szExe[256];
      int count = 0;
      DIR* proc = opendir("/proc");
      struct dirent* file;
      int64_t start = getCurrentTime();
      while((file = readdir(proc)) != NULL)
        {
           //把当前目录.,上一级目录..及隐藏文件都去掉,避免死循环遍历目录
            if(strncmp(file->d_name, ".", 1) == 0)
              {
                continue;
              }
            if(file->d_name[0]>='0' && file->d_name[0]<='9')
              {
                memset(szExe,0,256);
                strcpy(szExe, "/proc/");
                strcat(szExe, file->d_name);
                strcat(szExe, "/exe");
                readlink(szExe, szExe, 256);
                if(strcmp(szExe,"/usr/lib/firefox/firefox") == 0)
                {
                  count ++;
                }
              }
        }
      int64_t end = getCurrentTime();
      printf("%d,耗时:%ld",count,(end-start));
      return closedir(proc);
    }
    
    
    6,耗时:1
    

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK