Linux API 列出正在运行的进程?

2024-10-09 09:10:00
admin
原创
75
摘要:问题描述:我需要一个 C/C++ API,它允许我列出 Linux 系统上正在运行的进程,并列出每个进程打开的文件。我不想直接读取 /proc/ 文件系统。有人能想到办法做到这一点吗?解决方案 1:http://procps.sourceforge.net/http://procps.cvs.sourcefo...

问题描述:

我需要一个 C/C++ API,它允许我列出 Linux 系统上正在运行的进程,并列出每个进程打开的文件。

不想直接读取 /proc/ 文件系统。

有人能想到办法做到这一点吗?


解决方案 1:

http://procps.sourceforge.net/

http://procps.cvs.sourceforge.net/viewvc/procps/procps/proc/readproc.c?view=markup

是 ps 和其他进程工具的源代码。它们确实使用了 proc(表明这可能是常规且最佳的方式)。它们的源代码非常易读。文件

/procps-3.2.8/proc/readproc.c

可能有用。ephemient 还提出了一个有用的建议,即链接到libproc提供的 API ,该 API 应该在您的存储库中可用(或者应该说已经安装),但您需要使用“-dev”变体来获取标题和其他内容。

祝你好运

解决方案 2:

如果你不想从 /proc 读取,那么你可以考虑编写一个内核模块来实现你自己的系统调用。你的系统调用应该被编写成可以获取当前进程的列表,例如:

/* ProcessList.c 
    Robert Love Chapter 3
    */
    #include < linux/kernel.h >
    #include < linux/sched.h >
    #include < linux/module.h >

    int init_module(void) {
        struct task_struct *task;
        for_each_process(task) {
              printk("%s [%d]
",task->comm , task->pid);
        }
        return 0;
    }
   
    void cleanup_module(void) {
        printk(KERN_INFO "Cleaning Up.
");
    }

上面的代码取自我的文章 http://linuxgazette.net/133/saha.html 。一旦您有了自己的系统调用,您就可以从用户空间程序中调用它。

解决方案 3:

下面是(C/C++):

您可以在这里找到它:
http ://ubuntuforums.org/showthread.php?t=657097

本质上,它所做的就是循环遍历中的所有数字文件夹/proc/<pid>,然后对执行 readlink /proc/<pid>/exe,或者如果你想要命令行参数cat /proc/<pid>/cmdline

进程打开的文件描述符在 中/proc/<pid>/fd/<descriptor>,您可以通过在每个符号链接上执行 readlink 来获取文件名,例如readlink /proc/<pid>/fd/<descriptor>。fd 可以是设备(如 /dev/null)、套接字或文件,甚至可能更多。

包括 <unistd.h>

ssize_t readlink(const char path, char buf, size_t bufsiz);

成功时,readlink() 返回 buf 中放置的字节数。

出错时,返回 -1 并设置 errno 以指示错误。

顺便说一句,这与readproc.c所做的事情相同(或至少曾经做过)。

当然,希望他们这样做时没有缓冲区溢出的可能性。

#ifndef __cplusplus
    #define _GNU_SOURCE
#endif

#include &lt;unistd.h>
#include &lt;dirent.h>
#include &lt;sys/types.h> // for opendir(), readdir(), closedir()
#include &lt;sys/stat.h> // for stat()

#ifdef __cplusplus
    #include &lt;iostream>
    #include &lt;cstdlib>
    #include &lt;cstring>
    #include &lt;cstdarg>
#else
    #include &lt;stdio.h>
    #include &lt;stdlib.h>
    #include &lt;string.h>
    #include &lt;stdarg.h>
#endif


#define PROC_DIRECTORY &quot;/proc/&quot;
#define CASE_SENSITIVE    1
#define CASE_INSENSITIVE  0
#define EXACT_MATCH       1
#define INEXACT_MATCH     0


int IsNumeric(const char* ccharptr_CharacterList)
{
    for ( ; *ccharptr_CharacterList; ccharptr_CharacterList++)
        if (*ccharptr_CharacterList &lt; &#039;0&#039; || *ccharptr_CharacterList > &#039;9&#039;)
            return 0; // false
    return 1; // true
}


int strcmp_Wrapper(const char *s1, const char *s2, int intCaseSensitive)
{
    if (intCaseSensitive)
        return !strcmp(s1, s2);
    else
        return !strcasecmp(s1, s2);
}

int strstr_Wrapper(const char* haystack, const char* needle, int intCaseSensitive)
{
    if (intCaseSensitive)
        return (int) strstr(haystack, needle);
    else
        return (int) strcasestr(haystack, needle);
}


#ifdef __cplusplus
pid_t GetPIDbyName(const char* cchrptr_ProcessName, int intCaseSensitiveness, int intExactMatch)
#else
pid_t GetPIDbyName_implements(const char* cchrptr_ProcessName, int intCaseSensitiveness, int intExactMatch)
#endif
{
    char chrarry_CommandLinePath[100]  ;
    char chrarry_NameOfProcess[300]  ;
    char* chrptr_StringToCompare = NULL ;
    pid_t pid_ProcessIdentifier = (pid_t) -1 ;
    struct dirent* de_DirEntity = NULL ;
    DIR* dir_proc = NULL ;

    int (*CompareFunction) (const char*, const char*, int) ;

    if (intExactMatch)
        CompareFunction = &amp;strcmp_Wrapper;
    else
        CompareFunction = &amp;strstr_Wrapper;


    dir_proc = opendir(PROC_DIRECTORY) ;
    if (dir_proc == NULL)
    {
        perror(&quot;Couldn&#039;t open the &quot; PROC_DIRECTORY &quot; directory&quot;) ;
        return (pid_t) -2 ;
    }

    // Loop while not NULL
    while ( (de_DirEntity = readdir(dir_proc)) )
    {
        if (de_DirEntity->d_type == DT_DIR)
        {
            if (IsNumeric(de_DirEntity->d_name))
            {
                strcpy(chrarry_CommandLinePath, PROC_DIRECTORY) ;
                strcat(chrarry_CommandLinePath, de_DirEntity->d_name) ;
                strcat(chrarry_CommandLinePath, &quot;/cmdline&quot;) ;
                FILE* fd_CmdLineFile = fopen (chrarry_CommandLinePath, &quot;rt&quot;) ;  // open the file for reading text
                if (fd_CmdLineFile)
                {
                    fscanf(fd_CmdLineFile, &quot;%s&quot;, chrarry_NameOfProcess) ; // read from /proc/&lt;NR>/cmdline
                    fclose(fd_CmdLineFile);  // close the file prior to exiting the routine

                    if (strrchr(chrarry_NameOfProcess, &#039;/&#039;))
                        chrptr_StringToCompare = strrchr(chrarry_NameOfProcess, &#039;/&#039;) +1 ;
                    else
                        chrptr_StringToCompare = chrarry_NameOfProcess ;

                    //printf(&quot;Process name: %s
&quot;, chrarry_NameOfProcess);
                    //printf(&quot;Pure Process name: %s
&quot;, chrptr_StringToCompare );

                    if ( CompareFunction(chrptr_StringToCompare, cchrptr_ProcessName, intCaseSensitiveness) )
                    {
                        pid_ProcessIdentifier = (pid_t) atoi(de_DirEntity->d_name) ;
                        closedir(dir_proc) ;
                        return pid_ProcessIdentifier ;
                    }
                }
            }
        }
    }
    closedir(dir_proc) ;
    return pid_ProcessIdentifier ;
}

#ifdef __cplusplus
    pid_t GetPIDbyName(const char* cchrptr_ProcessName)
    {
        return GetPIDbyName(cchrptr_ProcessName, CASE_INSENSITIVE, EXACT_MATCH) ;
    }
#else
    // C cannot overload functions - fixed
    pid_t GetPIDbyName_Wrapper(const char* cchrptr_ProcessName, ... )
    {
        int intTempArgument ;
        int intInputArguments[2] ;
        // intInputArguments[0] = 0 ;
        // intInputArguments[1] = 0 ;
        memset(intInputArguments, 0, sizeof(intInputArguments) ) ;
        int intInputIndex ;
        va_list argptr;

        va_start( argptr, cchrptr_ProcessName );
            for (intInputIndex = 0;  (intTempArgument = va_arg( argptr, int )) != 15; ++intInputIndex)
            {
                intInputArguments[intInputIndex] = intTempArgument ;
            }
        va_end( argptr );
        return GetPIDbyName_implements(cchrptr_ProcessName, intInputArguments[0], intInputArguments[1]);
    }

    #define GetPIDbyName(ProcessName,...) GetPIDbyName_Wrapper(ProcessName, ##__VA_ARGS__, (int) 15)

#endif

int main()
{
    pid_t pid = GetPIDbyName(&quot;bash&quot;) ; // If -1 = not found, if -2 = proc fs access error
    printf(&quot;PID %d
&quot;, pid);
    return EXIT_SUCCESS ;
}

解决方案 4:

如果你不这样做,那么我猜你使用的任何 API 最终都会读取 /proc 文件系统。以下是一些执行此操作的程序示例:

  • 每秒

  • 顶部

  • 进程

但不幸的是,这并不构成 API。

解决方案 5:

/procPS 和从中读取的所有其他工具(内核模块除外)/proc都是内核动态创建的特殊文件系统,以便用户模式进程可以读取原本只能由内核使用的数据。

因此,推荐的方式是从 读取/proc

您可以快速直观地查看/proc文件系统以了解其结构。每个进程都有一个/proc/pidpid 是进程 ID 号。此文件夹中有多个文件,其中包含有关当前进程的不同数据。如果您运行

strace ps -aux

您将看到程序如何ps从中读取这些数据/proc

解决方案 6:

不读取 /proc 的情况下执行此操作的唯一方法是调用“ps aux”,遍历每一行,读取第二列(PID)并用它调用 lsof -p [PID]。

...我建议阅读/proc;)

解决方案 7:

libprocpsprocps-ng项目有一个库。在 Ubuntu 13.04 上,如果您执行strace ps,则可以看到ps使用libprocps

解决方案 8:

读取 proc 并不难。我无法用 C++ 向您展示,但以下 D 代码应该可以为您指明正确的方向:

导入 std.stdio;
导入 std.string;
导入 std.文件;
导入 std.regexp;
导入 std.c.linux.linux;

别名 std.string.split 爆炸;

字符串 srex = &quot;^/proc/[0-9]+$&quot;;
字符串 trex = &quot;状态:[     ][SR]&quot;;
正则表达式 rex;
正则表达式 rext;

   字符串[] scanPidDirs(字符串目标)
   {
      字符串[]结果;

      bool 回调(DirEntry* de)
      {
         如果 (de.isdir)
         {
            如果 (rex.find(de.name) >= 0)
            {
                字符串[] a = explosive(de.name, &quot;/&quot;);
                字符串pid = a[a.length-1];
                字符串 x = cast(string) std.file.read(de.name ~ &quot;/status&quot;);
                int n = rext.find(x);
                如果 (n >= 0)
                {
                    x = cast(string) std.file.read(de.name ~ &quot;/cmdline&quot;);
                    // 这是以空值结尾的
                    如果(x.长度)x.长度=x.长度-1;
                    a = 爆炸(x,“/”);
                    如果 (a.长度)
                       x = a[a.长度-1];
                    别的
                       x =“”;
                     如果 (x == 目标)
                    {
                        结果 ~= pid ~ &quot;/&quot; ~x;
                    }
                }
             }
          }
          返回 true;
      }

      listdir(“/proc”,&callback);
      返回结果.dup;
   }

void main(字符串[] 参数)
{
    rex = 新的 RegExp(srex);
    rext = 新的 RegExp(trex);
    字符串[] a = scanPidDirs(args[1]);
    如果 (!a.长度)
    {
        writefln(&quot;未找到&quot;);
        返回;
    }
    writefln(&quot;%d 个匹配的进程&quot;, a.length);
    foreach (s; a)
    {
       字符串[] p = 爆炸(s,“/”);
       int pid = atoi(p[0]);
       writef(&quot;停止 %s (%d)?&quot;, s, pid);
       字符串 r = readln();
       如果 (r == &quot;Y
&quot; || r == &quot;y
&quot;)
          杀死(pid,SIGUSR1);
    }
}

解决方案 9:

通过名称轻松找到任何进程的 pid

pid_t GetPIDbyName(char* ps_name)
{

    FILE *fp;
    char *cmd=(char*)calloc(1,200);
    sprintf(cmd,&quot;pidof %s&quot;,ps_name);
    fp=popen(cmd,&quot;r&quot;);
    fread(cmd,1,200,fp);
    fclose(fp);
    return atoi(cmd);
}
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用