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

2024-10-09 09:10:00
admin
原创
205
摘要:问题描述:我需要一个 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);
}
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用