如何监控多个进程,如果一个进程结束,我想运行一些代码。
我已经找到了几个使用轮询来实现这一点的例子,但我正在寻找一种在进程死亡时获得推送(可能是由操作系统)的方法。用C或C++可以做到这一点吗?它应该可以在任何现代Linux上运行。
如果有机会,我希望在不需要root权限的情况下这样做。
编辑:
整个程序的工作是监控这些过程,并将这些信息发送到另一个服务器,在那里它被集成到一个网站中。
我还没有启动这些进程,但我可以确保它们是以同一用户身份启动的。
我认为这应该是可能的,因为Linux下的top / ps命令也会给出您尚未启动的进程的信息。
发布于 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),readdir,closedir(3),sleep(3)每隔几秒钟扫描一次/proc/。顺便说一句,这在理论上是不可靠的(原则上,实际上不是,内核可能会在几秒钟内重用相同的pid ),并且可能不会捕获所有短暂的进程(例如ls外壳命令)。
top(1)实用程序很可能正在执行这种定期扫描/proc的操作。您可以通过深入研究top的源代码或通过strace(1)-ing it来检查它。
如果您的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),最后在一些<代码>C32或<代码>C33或<代码>C34上send(2)或write(2)一些消息,并在您的监视器中使用基于<代码>C35的<代码>C36。如果你可以通过你的显示器获得所有的程序fork-ed,事情也会有所不同(使用waitpid...)。请参阅我的execicar.c程序以获取灵感。
发布于 2016-01-15 18:03:05
您可以将auditd守护程序配置为在进程结束时创建审核记录(日志行)。然后用inotify监控auditd日志文件。
前提是您有权访问auditd配置及其日志文件。
发布于 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
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");
}https://stackoverflow.com/questions/34800568
复制相似问题