linux下进程结束时如何得到通知?
Posted
技术标签:
【中文标题】linux下进程结束时如何得到通知?【英文标题】:How to get notified when a process ends under linux? 【发布时间】:2016-04-20 10:15:05 【问题描述】:如何监控多个进程,如果一个进程结束,我想运行一些代码。
我找到了几个使用轮询来实现此目的的示例,但我正在寻找一种在进程终止时被推送(可能由操作系统)的方法。这可以用 C 或 C++ 实现吗?它应该可以在任何现代 Linux 上运行。
如果有任何机会,我想在不需要 root 权限的情况下这样做。
编辑:
整个程序的工作是监控这些过程并将这些信息发送到另一个服务器,然后将其集成到网站中。
我还没有启动这些进程,但我可以确保它们是作为同一用户启动的。
我认为这应该是可能的,因为 Linux 下的 top / ps 命令还可以为您提供有关您尚未启动的进程的信息。
【问题讨论】:
问题应该是“这在 Linux 上是否可行”。那么C部分就没有问题了。 关于 root:您是否可以只收到有关您的用户进程的通知? (我什至根本不知道这样的通知是否可能,但如果是,我确信只有 root 才能为 all 进程执行此操作) 我怀疑是否有人使用轮询来查找进程是否已终止。wait()
或 sigaction() /w SIGCHLD
.
看***.com/a/28602298/3134621
@EOF 这个只能对子进程执行,一般不行
【参考方案1】:
注意 /proc/ 目录为每个正在运行的进程的 PID 保存一个目录 例如 /proc/1 是 PID 1
在该目录下有 cmdline 文件,可用于确定 PID 的命令,即: 猫 /proc/1/cmdline /usr/lib/systemd/systemd
您可以遍历 /proc/[09]* 目录来查找与您要查找的内容匹配的 cmdline,当您匹配该命令时,您可以简单地检查 cmdline 是否仍然与原始命令匹配(可以是相同的 PID如果它已终止,则用于另一个进程
这里有一段简单的代码可以完成这项工作: 我还没有写大部分的纠错(如果找不到应用程序,程序会崩溃,其他一些导致段错误的错误) #包括 #包括 #包括
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");
【讨论】:
这是轮询,OP 已经声明有代码。问题是 notification 是否可行。【参考方案2】:一般而言,在 Linux 上,您无法收到有关非子进程或进程组或会话之外的进程的通知(使用 waitpid(2) 或 SIGCHLD
-see signal(7)- ...)。
在某些 Linux 上,您的(非 root)进程甚至可能不允许查询其他进程的存在。
当然,您可能会定期扫描/proc/
(每个进程有一个以数字命名的目录,例如/proc/1234/
用于pid 1234 的进程,请参阅proc(5)),您可以定期扫描(例如使用readdir(3)... ) 但您无法收到通知(请参阅inotify(7),对于/proc/
之类的伪文件系统,它不起作用 ...)关于其中的更改。注意/proc/
是一个伪文件系统,访问它不涉及任何磁盘IO,所以很快。
所以你可以做的是每隔几秒钟使用opendir(3)、readdir
、closedir(3)、sleep(3) 在循环中扫描/proc/
。顺便说一句,理论上不是防故障的(原则上,不是在实践中,内核可能会在几秒钟内重用相同的 pid),并且可能不会捕获所有 short-living 进程(如ls
shell 命令)。
/proc
的这种定期扫描很可能是 top(1) 实用程序正在执行的操作。您可以通过深入了解top
的源代码或strace(1)-ing 来检查它。
如果您的 C 代码已经知道某个进程的 pid 并且只是想检查该进程是否存在,它可以使用带有信号编号 0 的kill(2)。
另见systemd & credentials(7)。
如果您可以更改被监控程序的代码或替换它们(例如,通过您的小型 C 程序包装它们),情况就会大不相同;例如您可以用/usr/local/bin/foo-wrapper
替换/usr/bin/foo
并编码foo-wrapper.c
其中fork
-s & exec
-s 原始/usr/bin/foo
然后waitpid(2) 就可以了,最后send(2) 或write(2) 一些消息在某些socket(7) 或fifo(7) 或pipe(7) 上,并在您的监视器中使用基于poll(2) 的event loop。如果您可以通过监视器获取所有程序fork
-ed,那么情况也会有所不同(使用waitpid
...)。请参阅我的 execicar.c 程序以获取灵感。
【讨论】:
【参考方案3】:您可以配置auditd
守护程序以在进程结束时创建审计记录(日志行)。然后用inotify
监控auditd
日志文件。
前提是您有权访问auditd
配置及其日志文件。
【讨论】:
以上是关于linux下进程结束时如何得到通知?的主要内容,如果未能解决你的问题,请参考以下文章