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

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

我不想直接读取/ proc / file系统。

任何人都可以想办法做到这一点?

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发布的一个有用的build议是链接到libproc提供的API,它应该在您的仓库中可用(或者已经安装,我会说),但是您将需要“-dev”变体的头和什么不是。

祝你好运

如果你不想从'/ 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]\n",task->comm , task->pid); } return 0; } void cleanup_module(void) { printk(KERN_INFO "Cleaning Up.\n"); } 

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

如果你不这样做,那么我猜你将使用的任何API将最终读取/ proc文件系统。 下面是一些程序的例子:

  • QPS
  • HTOP
  • procps的

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

在这里你去(C / C ++):

你可以在这里find它: http : //ubuntuforums.org/showthread.php?t=657097

 #ifndef __cplusplus #define _GNU_SOURCE #endif #include <unistd.h> #include <dirent.h> #include <sys/types.h> // for opendir(), readdir(), closedir() #include <sys/stat.h> // for stat() #ifdef __cplusplus #include <iostream> #include <cstdlib> #include <cstring> #include <cstdarg> #else #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #endif #define PROC_DIRECTORY "/proc/" #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 < '0' || *ccharptr_CharacterList > '9') 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 = &strcmp_Wrapper; else CompareFunction = &strstr_Wrapper; dir_proc = opendir(PROC_DIRECTORY) ; if (dir_proc == NULL) { perror("Couldn't open the " PROC_DIRECTORY " directory") ; 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, "/cmdline") ; FILE* fd_CmdLineFile = fopen (chrarry_CommandLinePath, "rt") ; // open the file for reading text if (fd_CmdLineFile) { fscanf(fd_CmdLineFile, "%s", chrarry_NameOfProcess) ; // read from /proc/<NR>/cmdline fclose(fd_CmdLineFile); // close the file prior to exiting the routine if (strrchr(chrarry_NameOfProcess, '/')) chrptr_StringToCompare = strrchr(chrarry_NameOfProcess, '/') +1 ; else chrptr_StringToCompare = chrarry_NameOfProcess ; //printf("Process name: %s\n", chrarry_NameOfProcess); //printf("Pure Process name: %s\n", 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("bash") ; // If -1 = not found, if -2 = proc fs access error printf("PID %d\n", pid); return EXIT_SUCCESS ; } 

PS和其他所有工具(除了内核模块)从/proc读取。 /proc是由内核在运行时创build的一个特殊的文件系统,因此用户模式进程可以读取否则只能用于内核的数据。

因此推荐的方法是从/proc读取。

您可以快速直观地查看/proc文件系统,以了解其结构。 每个进程都有一个/proc/pid ,其中pid是进程标识号。 在这个文件夹中有几个文件,其中包含有关当前进程的不同数据。 如果你跑步

 strace ps -aux 

你会看到程序ps如何从/proc读取这个数据。

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

…我build议阅读/ proc;)

procps-ng项目中有一个库libprocps 。 在Ubuntu 13.04上,如果你使用strace ps ,那么你可以看到ps使用libprocps

阅读过程不是太糟糕。 我不能用C ++展示你,但是下面的D代码应该指向你正确的方向:

导入std.stdio;
导入std.string;
导入std.file;
导入std.regexp;
导入std.c.linux.linux;

别名std.string.split爆炸;

 string srex =“^ / proc / [0-9] + $”;
stringtrex =“状态:[\ t] [SR]”;
 RegExp rex;
 RegExp rext;

   string[] scanPidDirs(string目标)
    {
      string[]结果;

      布尔callback(DirEntry * de)
       {
         如果(de.isdir)
          {
            如果(rex.find(de.name)> = 0)
             {
                 string [] a = explode(de.name,“/”);
                 string pid = a [a.length-1];
                 string x = cast(string)std.file.read(de.name〜“/ status”);
                 int n = rext.find(x);
                如果(n> = 0)
                 {
                     x = cast(string)std.file.read(de.name〜“/ cmdline”);
                     //这是空的终止
                     if(x.length)x.length = x.length-1;
                     a = explode(x,“/”);
                    如果(a.length)
                        x = a [a.length-1];
                    其他
                        x =“”;
                     如果(x ==目标)
                     {
                        结果〜= pid〜“/”〜x;
                     }
                 }
              }
           }
          返回true;
       }

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

 void main(string [] args)
 {
     rex = new RegExp(srex);
     rext = new RegExp(trex);
     string [] a = scanPidDirs(args [1]);
    如果(!a.length)
     {
         writefln(“未find”);
        返回;
     }
     writefln(“%d匹配进程”,a.length);
     foreach(s; a)
     {
        string [] p = explode(s,“/”);
        int pid = atoi(p [0]);
        writef(“Stop%s(%d)?”,s,pid);
       stringr = readln();
        if(r ==“Y \ n”|| r ==“y \ n”)
           kill(pid,SIGUSR1);
     }
 }

简单的方法来命名任何进程的PID名称

 pid_t GetPIDbyName(char* ps_name) { FILE *fp; char *cmd=(char*)calloc(1,200); sprintf(cmd,"pidof %s",ps_name); fp=popen(cmd,"r"); fread(cmd,1,200,fp); fclose(fp); return atoi(cmd); } 
 #include <stdio.h> #include <stdlib.h> #include <string.h> char *mystrstr(const char *haystack,const char *needle); main() { char *str1="abc dc abcd abce"; char *str2="ab"; char *ptr=NULL; int cnt=0; int offset=0; while(*str1) { ptr=mystrstr(str1,str2); if(ptr==NULL) break; cnt++; offset=ptr-str1+strlen(str2); str1=str1+offset; } printf("Num of substr [%s] = %d\n",str2,cnt ); } char *mystrstr(const char *haystack,const char *needle) { int i=0,j=1; for(;haystack[i];i++) { if(needle[0]==haystack[i]) { for(;needle[j];j++) { if(needle[j]==haystack[i+j] ) { if(needle[j]!='\0') continue; } else break; } if(needle[j]=='\0') return haystack + i; else if(haystack[i]!='\0') continue; } if(haystack[i]=='\0') return NULL; } }