确定程序是否正在运行

在C中,我怎样才能以编程的方式find一个进程是否已经在Linux / Ubuntu上运行,以避免启动两次? 我正在寻找类似于pidof的东西。

Solutions Collecting From Web of "确定程序是否正在运行"

您可以在/proc遍历pid条目,并在cmdline文件中检查您的进程,或者在exe链接上执行readlink (以下使用第一种方法)。

 #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <dirent.h> #include <sys/types.h> pid_t proc_find(const char* name) { DIR* dir; struct dirent* ent; char* endptr; char buf[512]; if (!(dir = opendir("/proc"))) { perror("can't open /proc"); return -1; } while((ent = readdir(dir)) != NULL) { /* if endptr is not a null character, the directory is not * entirely numeric, so ignore it */ long lpid = strtol(ent->d_name, &endptr, 10); if (*endptr != '\0') { continue; } /* try to open the cmdline file */ snprintf(buf, sizeof(buf), "/proc/%ld/cmdline", lpid); FILE* fp = fopen(buf, "r"); if (fp) { if (fgets(buf, sizeof(buf), fp) != NULL) { /* check the first token in the file, the program name */ char* first = strtok(buf, " "); if (!strcmp(first, name)) { fclose(fp); closedir(dir); return (pid_t)lpid; } } fclose(fp); } } closedir(dir); return -1; } int main(int argc, char* argv[]) { if (argc == 1) { fprintf("usage: %s name1 name2 ...\n", argv[0]); return 1; } int i; for(int i = 1; i < argc; ++i) { pid_t pid = proc_find(argv[i]); if (pid == -1) { printf("%s: not found\n", argv[i]); } else { printf("%s: %d\n", argv[i], pid); } } return 0; } 

有一些方法可以避免/proc使用(可能有很好的理由,例如/proc可能根本就没有安装,或者它可能已经被链接到一些欺骗性的东西,或者这个pid已经隐藏在/proc )。 当然,下面的方法看起来不太好,我希望有一个适当的API!

无论如何,从Unix编程常见问题解答 :

对信号编号使用kill()为0。 这个调用有四个可能的结果:

  • kill()返回0

    这意味着一个过程与给定的PID存在,系统将允许您发送信号给它。 这个过程是否是一个僵尸是依赖于系统的。

  • kill()返回-1, errno == ESRCH

    给定的PID不存在任何进程,或者安全性增强导致系统拒绝其存在。 (在某些系统上,这个过程可能是一个僵尸。)

  • kill()返回-1, errno == EPERM

    系统不会允许你杀死指定的进程。 这意味着要么存在过程(也可能是僵尸),要么存在苛刻的安全增强(例如,你的过程不允许向任何人发送信号)。

  • kill()返回-1,其他值为errno

    你有麻烦了!

最常用的技术是假定EPERM成功或失败意味着这个过程是存在的,任何其他的错误都意味着它不存在。

这与John Ledbetter发布的代码相同。 由于前者给出进程状态和进程名称,所以引用/ proc / pid /目录中名为stat的文件比cmdline更好。 cmdline文件给出了进程启动的完整参数。 所以这在某些情况下失败了。 无论如何,约翰的想法是好的。 在这里,我发布了约翰的修改后的代码。 我正在寻找在Linux中的C代码来检查DHCP是否正在运行。 有了这个代码,我能够做到这一点。 我希望这可能对像我这样的人有用。

 #include <sys/types.h> #include <dirent.h> #include<unistd.h> #include <stdio.h> #include <string.h> #include <stdlib.h> pid_t proc_find(const char* name) { DIR* dir; struct dirent* ent; char buf[512]; long pid; char pname[100] = {0,}; char state; FILE *fp=NULL; if (!(dir = opendir("/proc"))) { perror("can't open /proc"); return -1; } while((ent = readdir(dir)) != NULL) { long lpid = atol(ent->d_name); if(lpid < 0) continue; snprintf(buf, sizeof(buf), "/proc/%ld/stat", lpid); fp = fopen(buf, "r"); if (fp) { if ( (fscanf(fp, "%ld (%[^)]) %c", &pid, pname, &state)) != 3 ){ printf("fscanf failed \n"); fclose(fp); closedir(dir); return -1; } if (!strcmp(pname, name)) { fclose(fp); closedir(dir); return (pid_t)lpid; } fclose(fp); } } closedir(dir); return -1; } int main(int argc, char* argv[]) { int i; if (argc == 1) { printf("usage: %s name1 name2 ...\n", argv[0]); return 1; } for( i = 1; i < argc; ++i) { pid_t pid = proc_find(argv[i]); if (pid == -1) { printf("%s: not found\n", argv[i]); } else { printf("%s: %d\n", argv[i], pid); } } return 0; } 

pidof通过遍历/proc文件系统工作 。 在C中,你可以通过枚举/proc来做类似的事情。 为每个X打开/proc/X/cmdline ,其中X是一个或多个十进制数字的列表。 我不知道你是否有任何可移植性的要求,但要记住,如果你要依赖/proc的可用性。

通过包装程序的启动和维护一个PID文件,在类UNIX系统上这个问题更常见。 有关此方法的经典示例,请参阅/etc/init.d/* 。 您需要小心以确保读取写入PID文件的代码以安全的方式(原子地)执行。 如果你的目标操作系统具有更强大的init(比如systemd ),那么你可以把这个工作从源代码中解脱出来。