首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在linux下如何在进程结束时得到通知?

在linux下如何在进程结束时得到通知?
EN

Stack Overflow用户
提问于 2016-01-15 05:59:06
回答 3查看 4.9K关注 0票数 8

如何监控多个进程,如果一个进程结束,我想运行一些代码。

我已经找到了几个使用轮询来实现这一点的例子,但我正在寻找一种在进程死亡时获得推送(可能是由操作系统)的方法。用C或C++可以做到这一点吗?它应该可以在任何现代Linux上运行。

如果有机会,我希望在不需要root权限的情况下这样做。

编辑:

整个程序的工作是监控这些过程,并将这些信息发送到另一个服务器,在那里它被集成到一个网站中。

我还没有启动这些进程,但我可以确保它们是以同一用户身份启动的。

我认为这应该是可能的,因为Linux下的top / ps命令也会给出您尚未启动的进程的信息。

EN

回答 3

Stack Overflow用户

发布于 2016-01-15 15:35:47

通常在Linux上你不能得到通知(使用waitpid(2)SIGCHLD -see signal(7)- ...)关于非子进程,或进程组或会话之外的进程。

在某些Linux上,您的(非根)进程可能甚至不允许查询其他进程的存在。

当然,您可能会定期扫描/proc/ (每个进程有一个以数字命名的目录,例如pid为1234的进程的/proc/1234/,请参阅proc(5)) (例如,使用readdir(3)...)但是您不会收到通知(请参阅inotify(7),它不适用于/proc/等伪文件系统...)关于它内部的变化。注意,/proc/是一个伪文件系统,访问它不涉及任何磁盘IO,因此非常快。

所以你可以做的是在循环中使用opendir(3)readdirclosedir(3)sleep(3)每隔几秒钟扫描一次/proc/。顺便说一句,这在理论上是不可靠的(原则上,实际上不是,内核可能会在几秒钟内重用相同的pid ),并且可能不会捕获所有短暂的进程(例如ls外壳命令)。

top(1)实用程序很可能正在执行这种定期扫描/proc的操作。您可以通过深入研究top的源代码或通过strace(1)-ing it来检查它。

如果您的C代码已经知道某个进程的pid,并且只是想检查该进程是否存在,那么它可以使用信号号为0的kill(2)

另请参阅systemdcredentials(7)

如果您可以更改被监控程序的代码或替换它们(例如,通过您的小C程序包装它们),事情将非常不同;例如,您可以用/usr/local/bin/foo-wrapper替换/usr/bin/foo,并编写一个foo-wrapper.c,其中fork-s & exec-s原始/usr/bin/foo,然后在其上waitpid(2),最后在一些<代码>C32或<代码>C33或<代码>C34上send(2)write(2)一些消息,并在您的监视器中使用基于<代码>C35的<代码>C36。如果你可以通过你的显示器获得所有的程序fork-ed,事情也会有所不同(使用waitpid...)。请参阅我的execicar.c程序以获取灵感。

票数 7
EN

Stack Overflow用户

发布于 2016-01-15 18:03:05

您可以将auditd守护程序配置为在进程结束时创建审核记录(日志行)。然后用inotify监控auditd日志文件。

前提是您有权访问auditd配置及其日志文件。

票数 4
EN

Stack Overflow用户

发布于 2016-01-15 06:55:22

请注意,/proc/目录为每个运行进程的PID保存一个目录,例如,/proc/1的PID为1

在该目录下有cmdline文件,该文件可用于确定PID的命令,即: cat /proc/1/cmdline /usr/lib/systemd/systemd

您可以遍历/proc/09*指令来查找与您正在寻找的命令相匹配的cmdline,当您匹配该命令时,您可以简单地检查cmdline是否仍然与原始的cmdline匹配(如果另一个进程已经终止,则可以将相同的PID用于另一个进程

下面是完成这项工作的一段简单代码:我还没有编写大部分的纠错代码(如果找不到应用程序,程序就会崩溃,还有一些其他错误会导致段错误) #include #include #include

代码语言:javascript
复制
int main(int argc, char* argv[]) {
  if (argc != 2){
    printf("usage:\nproc <processname>\n");
    return 2;
  }
  char * processName = argv[1];
  int pid = 0;
  FILE *processFile;
  char *monitoredProcess;
  DIR *root;
  struct dirent *dir;
  root = opendir("/proc/");
if (root)
  {
    int reading = 0;
    while((dir=readdir(root))!=NULL && reading==0)
    {
     // printf("dir name:%i\n",dir->d_ino);
      if (dir->d_name[0] > 47 && dir->d_name[0] < 58) {
    char directory[128];
    strcpy(directory,"/proc/");
        strcat(directory,dir->d_name);
    strcat(directory,"/cmdline");
    processFile = fopen(directory,"r");
    if (processFile == NULL) {
      printf("Error");
      return 1;
    }
    char line[2048];
    while (fgets(line, sizeof line, processFile) != NULL) {
      if(strstr(line,processName)) {
        printf("%s\n",directory);
        monitoredProcess = directory;
        reading = 1;
      }
      //the pid has been determined at this point, now to monitor
    }
      }
    }
    //monitoring
    printf("monitoring %s\n",monitoredProcess);
    while(processFile=fopen(monitoredProcess,"r")) {
      char line[2048];
      while (fgets(line, sizeof line, processFile) != NULL) {
    if(strstr(line,processName) == NULL)
      printf("application terminated\n");
      }
      sleep(3);
      fclose(processFile);
    }
  } else
    printf("unable to open folder\n");
}
票数 -3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34800568

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档